Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions src/main/java/org/patinanetwork/patchats/api/matches/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
### Overview

- This API lists matches from database

### Endpoints

| Method | Path | Description |
|--------|------|-------------|
| GET | /api/matches/{year} | List pairings by year |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have a /api/matches/list endpoint that takes in search params

| GET | /api/matches/{year}/{month} | List pairings by month |
| GET | /api/matches/member/{id} | List pairings by member id |


Response: `ApiResponder<Match[]>`
```typescript
interface Match {
match_id: string // UUID
member_a_id: string // UUID
member_b_id: string // UUID
month: string // YYYY-MM, from match_cycles.run_at
status: string
}
```
* Figured a flat list is more flexible for rendering instead of grouping by month server side

## /api/matches/{year}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just have /api/matches/{match_cycle.id} instead of a year.

* Join on match_cycles, filtered by run_at within year
```sql
SELECT m.id, m.member_a_id, m.member_b_id, m.status,
to_char(c.run_at, 'YYYY-MM') AS month
FROM matches m
JOIN match_cycles c ON m.cycle_id = c.id

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change match_cycle.id to an int

WHERE c.run_at >= TIMESTAMPTZ '2026-01-01'
AND c.run_at < TIMESTAMPTZ '2027-01-01';
Comment on lines +33 to +34

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SQL query uses hardcoded dates '2026-01-01' and '2027-01-01' instead of parameterizing the {year} path variable. If implemented as written, the endpoint will ignore the year parameter and always return matches for 2026 only.

Fix: Replace with parameterized dates:

WHERE c.run_at >= TIMESTAMPTZ :year || '-01-01'
  AND c.run_at <  TIMESTAMPTZ (:year + 1) || '-01-01'
Suggested change
WHERE c.run_at >= TIMESTAMPTZ '2026-01-01'
AND c.run_at < TIMESTAMPTZ '2027-01-01';
WHERE c.run_at >= TIMESTAMPTZ :year || '-01-01'
AND c.run_at < TIMESTAMPTZ (:year + 1) || '-01-01';

Spotted by Graphite

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

```

## /api/matches/{year}/{month}
* Join on match_cycles, filtered by run_at within month
```sql
SELECT m.id, m.member_a_id, m.member_b_id, m.status,
to_char(c.run_at, 'YYYY-MM') AS month
FROM matches m
JOIN match_cycles c ON m.cycle_id = c.id
WHERE c.run_at >= TIMESTAMPTZ '2026-01-01'
AND c.run_at < TIMESTAMPTZ '2026-02-01';
```
Comment on lines +37 to +46

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to break this up by year


## /api/matches/member/{id}
* Filter matches by member id
```sql
SELECT m.id, m.member_a_id, m.member_b_id, m.status,
to_char(c.run_at, 'YYYY-MM') AS month
FROM matches m
JOIN match_cycles c ON m.cycle_id = c.id
WHERE m.member_a_id = :id
OR m.member_b_id = :id
```

### Layering

Controller:
- `MatchController` (`/api/matches`)
* `listByYear(year)`
* `listByMonth(year, month)`
* `listByMember(id)`

Repository: `MatchRepository` (Spring JDBC, `NamedParameterJdbcTemplate`)
- owns the SQL above; returns `List<Match>`

DTO: `Match` (interface Match)
- `ApiResponder<List<Match>>`


Loading