Skip to content

Commit e83b412

Browse files
committed
#11, add puzzle configs table
1 parent c619549 commit e83b412

File tree

11 files changed

+93
-14
lines changed

11 files changed

+93
-14
lines changed

Diff for: api/command/deliverPuzzle.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { FindBoothByTokenInput } from '@api/projection'
66

77
export type DeliverPuzzleInput = {
88
token: string
9+
eventId: string
910
delivererToken: string
1011
}
1112

@@ -60,7 +61,7 @@ export class DeliverPuzzleCommand implements Command<DeliverPuzzleInput, Deliver
6061
throw new PuzzledAlreadyDeliveredError()
6162
}
6263

63-
const config = await this.config.findById(booth.name)
64+
const config = await this.config.findById(input.eventId)
6465
if (!config) {
6566
throw new PuzzleDelivererNotFoundError()
6667
}

Diff for: api/repository/puzzleConfig.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import { type D1Database } from '@cloudflare/workers-types'
22
import { Repository } from '@/core'
33
import { Config } from '@/puzzle'
44

5+
type PuzzleConfigSchema = {
6+
event_id: string
7+
pieces: string
8+
}
9+
510
export class D1PuzzleConfigRepository implements Repository<Config> {
611
private readonly db: D1Database
712

@@ -10,7 +15,23 @@ export class D1PuzzleConfigRepository implements Repository<Config> {
1015
}
1116

1217
async findById(eventId: string): Promise<Config | null> {
13-
return new Config(eventId, '{"=":1}')
18+
const stmt = await this.db
19+
.prepare('SELECT * FROM puzzle_configs WHERE event_id = ?')
20+
.bind(eventId)
21+
const result = await stmt.first<PuzzleConfigSchema>()
22+
23+
if (!result) {
24+
return null
25+
}
26+
27+
const config = new Config(result.event_id)
28+
const pieces = JSON.parse(result.pieces)
29+
30+
for (const name in pieces) {
31+
config.addPiece(name, pieces[name])
32+
}
33+
34+
return config
1435
}
1536

1637
async save(_config: Config): Promise<void> {}

Diff for: features/puzzle_delivery.feature

+14-6
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,18 @@ Feature: Puzzle Delivery
33
Given there have some booths
44
| token | name | event_id |
55
| 1024914b-ee65-4728-b687-8341f5affa89 | COSCUP | SITCON |
6+
And event "SITCON" have a puzzle config
7+
"""
8+
{
9+
"pieces": {
10+
"=": 1
11+
}
12+
}
13+
"""
614
And there have some attendees
715
| token | event_id | display_name |
816
| f185f505-d8c0-43ce-9e7b-bb9e8909072d | COSCUP2023 | Aotoki |
9-
When I make a POST request to "/event/puzzle/deliver?token=1024914b-ee65-4728-b687-8341f5affa89":
17+
When I make a POST request to "/event/puzzle/deliver?token=1024914b-ee65-4728-b687-8341f5affa89&event_id=SITCON":
1018
"""
1119
{
1220
"receiver": "f185f505-d8c0-43ce-9e7b-bb9e8909072d"
@@ -24,7 +32,7 @@ Feature: Puzzle Delivery
2432
Given there have some attendees
2533
| token | event_id | display_name |
2634
| f185f505-d8c0-43ce-9e7b-bb9e8909072d | COSCUP2023 | Aotoki |
27-
When I make a POST request to "/event/puzzle/deliver?token=d9d09032-cdae-4da2-9f41-680ca64f2d21":
35+
When I make a POST request to "/event/puzzle/deliver?token=d9d09032-cdae-4da2-9f41-680ca64f2d21&event_id=SITCON":
2836
"""
2937
{
3038
"receiver": "f185f505-d8c0-43ce-9e7b-bb9e8909072d"
@@ -38,7 +46,7 @@ Feature: Puzzle Delivery
3846
}
3947
"""
4048
Scenario: POST /event/puzzle/deliver without booth token in querystring
41-
When I make a POST request to "/event/puzzle/deliver":
49+
When I make a POST request to "/event/puzzle/deliver?event_id=SITCON":
4250
"""
4351
{
4452
"receiver": "1cf41a53-4aea-452b-a204-6b0b52eee380"
@@ -52,7 +60,7 @@ Feature: Puzzle Delivery
5260
}
5361
"""
5462
Scenario: POST /event/puzzle/deliver without receiver token
55-
When I make a POST request to "/event/puzzle/deliver?token=f185f505-d8c0-43ce-9e7b-bb9e8909072d":
63+
When I make a POST request to "/event/puzzle/deliver?token=f185f505-d8c0-43ce-9e7b-bb9e8909072d&event_id=SITCON":
5664
"""
5765
{}
5866
"""
@@ -68,7 +76,7 @@ Feature: Puzzle Delivery
6876
Given there have some booths
6977
| token | name | event_id |
7078
| 1024914b-ee65-4728-b687-8341f5affa89 | COSCUP | SITCON |
71-
When I make a POST request to "/event/puzzle/deliver?token=1024914b-ee65-4728-b687-8341f5affa89":
79+
When I make a POST request to "/event/puzzle/deliver?token=1024914b-ee65-4728-b687-8341f5affa89&event_id=SITCON":
7280
"""
7381
{
7482
"receiver": "1cf41a53-4aea-452b-a204-6b0b52eee380"
@@ -93,7 +101,7 @@ Feature: Puzzle Delivery
93101
| id | type | aggregate_id | version | payload | occurred_at |
94102
| b44845bd-8bd2-428d-ad65-f6a619bf8a96 | AttendeeInitialized | f185f505-d8c0-43ce-9e7b-bb9e8909072d | 0 | { "displayName": "Aotoki" } | 2023-09-10 20:4:00 |
95103
| f41c7a07-d2f4-469a-ae16-4df251eddbf6 | PuzzleCollected | f185f505-d8c0-43ce-9e7b-bb9e8909072d | 1 | { "pieceName": "=", "giverName": "COSCUP" } | 2023-09-10 20:50:00 |
96-
When I make a POST request to "/event/puzzle/deliver?token=1024914b-ee65-4728-b687-8341f5affa89":
104+
When I make a POST request to "/event/puzzle/deliver?token=1024914b-ee65-4728-b687-8341f5affa89&event_id=SITCON":
97105
"""
98106
{
99107
"receiver": "f185f505-d8c0-43ce-9e7b-bb9e8909072d"

Diff for: features/support/mockSteps.ts

+14
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,20 @@ Given(
6464
}
6565
)
6666

67+
Given(
68+
'event {string} have a puzzle config',
69+
async function (this: WorkerWorld, eventId: string, body: string) {
70+
await createMockData(
71+
this.mock,
72+
'/puzzle/configs',
73+
JSON.stringify({
74+
event_id: eventId,
75+
...JSON.parse(body),
76+
})
77+
)
78+
}
79+
)
80+
6781
Given('there have some booths', async function (this: WorkerWorld, dataTable: DataTable) {
6882
await createMockData(this.mock, '/booths', JSON.stringify(dataTable.hashes()))
6983
})

Diff for: migrations/0015_add_puzzle_config.sql

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- Migration number: 0015 2023-12-13T13:44:13.922Z
2+
DROP TABLE IF EXISTS puzzle_configs;
3+
CREATE TABLE puzzle_configs (
4+
event_id VARCHAR(255) PRIMARY KEY,
5+
pieces TEXT NOT NULL
6+
);

Diff for: mock/api/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ export * from './rulesets'
44
export * from './reset'
55
export * from './puzzleActivityEvents'
66
export * from './puzzleStatEvents'
7+
export * from './puzzleConfigs'
78
export * from './booths'

Diff for: mock/api/puzzleConfigs.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { json, IRequest } from 'itty-router'
2+
import { D1Database } from '@cloudflare/workers-types'
3+
4+
type Env = {
5+
DB: D1Database
6+
}
7+
8+
export type CreatePuzzleConfigPayload = {
9+
event_id: string
10+
pieces: Record<string, number>
11+
}
12+
13+
export async function createPuzzleConfigHandler(req: IRequest, { DB }: Env) {
14+
const { event_id, pieces } = (await req.json()) as CreatePuzzleConfigPayload
15+
const stmt = await DB.prepare(`INSERT INTO puzzle_configs (event_id, pieces) VALUES (?, ?)`)
16+
const info = await stmt.bind(event_id, pieces ? JSON.stringify(pieces) : '{}').run()
17+
18+
return json(info)
19+
}

Diff for: mock/api/reset.ts

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export async function resetHandler(req: IRequest, { DB }: Env) {
1212
DB.prepare(`DELETE FROM rulesets`),
1313
DB.prepare(`DELETE FROM puzzle_activity_events`),
1414
DB.prepare(`DELETE FROM puzzle_stat_events`),
15+
DB.prepare(`DELETE FROM puzzle_configs`),
1516
DB.prepare(`DELETE FROM booths`),
1617
])
1718

Diff for: mock/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ router
1919
.post<IRequest, CF>('/booths', Api.createBoothHandler)
2020
.post<IRequest, CF>('/puzzle/activity_events', Api.createPuzzleActivityEventHandler)
2121
.post<IRequest, CF>('/puzzle/stat_events', Api.createPuzzleStatEventHandler)
22+
.post<IRequest, CF>('/puzzle/configs', Api.createPuzzleConfigHandler)
2223
.all('*', () => error(404))
2324

2425
export default {

Diff for: src/puzzle/config.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ export class Config implements Entity<string> {
44
readonly id: string
55
private _pieces: Record<string, number>
66

7-
constructor(id: string, pieces: string) {
7+
constructor(id: string) {
88
this.id = id
9-
this._pieces = JSON.parse(pieces)
9+
this._pieces = {}
1010
}
1111

1212
get pieces(): Record<string, number> {
13-
return this._pieces
13+
return { ...this._pieces }
14+
}
15+
16+
addPiece(name: string, ratio: number): void {
17+
this._pieces[name] = ratio
1418
}
1519
}

Diff for: worker/controller/puzzleDelivery.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export class DeliverPuzzleToUser extends OpenAPIRoute {
2222
receiver: new Str({ description: 'the attendee public token', required: false }),
2323
},
2424
parameters: {
25+
event_id: schema.EventIdQuery,
2526
token: schema.OptionalDelivererTokenQuery,
2627
},
2728
responses: {
@@ -36,18 +37,20 @@ export class DeliverPuzzleToUser extends OpenAPIRoute {
3637
}
3738

3839
async handle(request: PuzzleDeliveryRequest, env: unknown, context: unknown, data: Data) {
39-
const delivererTooken = request.query.token
40+
const delivererToken = request.query.token
41+
const eventId = request.query.event_id as string
4042
const { body } = data
4143
const receiverToken = isDeliverPuzzleForm(body) ? body.receiver : null
4244

43-
if (!delivererTooken || !receiverToken) {
45+
if (!delivererToken || !receiverToken) {
4446
throw new StatusError(400, 'token and receiver required')
4547
}
4648

4749
try {
4850
const result = await request.deliverPuzzle.execute({
4951
token: receiverToken,
50-
delivererToken: String(delivererTooken),
52+
eventId,
53+
delivererToken: String(delivererToken),
5154
})
5255

5356
return json<schema.PuzzleDeliveredResponse>({

0 commit comments

Comments
 (0)