Reconcile Projects schema.md with implementation decisions

Update the proposal doc to match what was actually built:
- client_id is uuid -> organisation (Client maps to organisation).
- property_id FKs are bigint (Property has a bigint PK).
- status/priority columns documented as text (values TBC).
- Drop the free-text uploaded_by column; note the existing bigint
  FK -> user is reused.
- Document the new minimal project_type table.
- Record that a "projects" file_source value was added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Daniel Roth 2026-07-17 14:17:41 +00:00
parent e452fc9ab2
commit b21be2e5cd

View file

@ -50,7 +50,21 @@ Project
# Proposed Schema
Conventions: bigint autoincrement primary keys for all new tables (and bigint FKs between them); FKs to pre-existing tables match the referenced PK's type (e.g. Property has an integer PK). `timestamp` columns default to `now()`, and status-like columns are Postgres enums (one enum type per column, values TBC).
> **Implementation note.** This document is the original proposal. Where the
> approved implementation diverges from it, the tables below have been updated
> and the change flagged inline as _(implemented: …)_. Summary of the divergences:
>
> - **"Client" maps to the existing `organisation` table**, whose PK is `uuid`.
> `project.client_id` is therefore a `uuid` FK, not `bigint`.
> - **Property has a `bigint` PK** (`bigserial`), not an integer one. Every
> `property_id` FK is `bigint`.
> - **`status` / `priority` columns are `text` for now**, not Postgres enums —
> their value sets are still TBC and an empty enum can't be created. Convert to
> `pgEnum` once the values are agreed.
> - **No new `uploaded_by` column** on `uploaded_files`; the existing
> `uploaded_by` `bigint` FK → user is reused.
Conventions: bigint autoincrement primary keys for all new tables (and bigint FKs between them); FKs to pre-existing tables match the referenced PK's type. `timestamp` columns default to `now()`. Status-like columns were proposed as Postgres enums but are implemented as `text` for now (values TBC).
## Project
@ -60,7 +74,7 @@ The aggregate root.
| ------------------------------ | ------- | -------- | -------------------------------- |
| id | bigint | No | Primary Key |
| name | varchar | No | |
| client_id | bigint | No | FK → Client |
| client_id | uuid | No | FK → Client _(implemented: uuid FK → existing `organisation` table)_ |
| project_type_id | bigint | No | FK → Project Type |
| description | text | Yes | |
| start_date | date | Yes | May be unknown at creation |
@ -71,6 +85,18 @@ The aggregate root.
---
## Project Type
Reference data defining the available project types. _(Implemented as a minimal
`project_type` table — extend when the required attributes are known.)_
| Column | Type | Nullable | Notes |
| ------ | ------- | -------- | ----------- |
| id | bigint | No | Primary Key |
| name | varchar | No | |
---
## Project Property
Bridging table between Project and Property — the relationship is many-to-many.
@ -79,7 +105,7 @@ Bridging table between Project and Property — the relationship is many-to-many
| ----------- | ------- | -------- | ------------------------------------------ |
| id | bigint | No | Primary Key |
| project_id | bigint | No | FK → Project |
| property_id | integer | No | FK → Property (existing table, integer PK) |
| property_id | bigint | No | FK → Property (existing table, bigint PK) |
Unique constraint on `(project_id, property_id)`.
@ -161,7 +187,7 @@ Example:
| start_date | date | Yes | Set as work progresses |
| due_date | date | Yes | |
| last_updated | timestamp | No | Default `now()`, refreshed on change |
| status | enum | No | Postgres enum; values TBC (e.g. not_started / in_progress / complete) |
| status | text | No | Values TBC — `text` for now, convert to Postgres enum once agreed (e.g. not_started / in_progress / complete) |
| status_description | text | Yes | Free-text commentary on the current status |
---
@ -226,9 +252,10 @@ The table already provides the file storage columns (`s3_file_bucket`, `s3_file_
| project_workstream_id | bigint | Yes | FK → Project Workstream; nullable for now — aim to make it NOT NULL for Projects uploads in future |
| project_workstream_evidence_requirement_id | bigint | Yes | FK → Project Workstream Evidence Requirement; null for ad-hoc uploads not tied to a requirement |
| project_workstream_contractor_id | bigint | Yes | FK → Project Workstream Contractor |
| uploaded_by | text | Yes | Free text for now — undecided whether contractors get individual or shared company accounts |
The `file_source` enum will likely need a new value for uploads originating from the Projects module.
_(The proposed free-text `uploaded_by` column was **not** added: the table already has an `uploaded_by` `bigint` FK → user, which Projects uploads reuse.)_
A `"projects"` value was added to the `file_source` enum for uploads originating from the Projects module.
---
@ -241,11 +268,11 @@ Represents work issued to a contractor.
| id | bigint | No | Primary Key |
| reference | varchar | No | Unique |
| project_workstream_contractor_id | bigint | No | FK → Project Workstream Contractor |
| property_id | integer | No | FK → Property (existing table, integer PK) |
| property_id | bigint | No | FK → Property (existing table, bigint PK) |
| project_workstream_stage_id | bigint | No | FK → Project Workstream Stage |
| status | enum | No | Postgres enum; values TBC |
| status | text | No | Values TBC — `text` for now, convert to Postgres enum once agreed |
| forecast_end | date | Yes | |
| priority | enum | Yes | Postgres enum; values TBC |
| priority | text | Yes | Values TBC — `text` for now, convert to Postgres enum once agreed |
---
@ -364,7 +391,7 @@ Or should assignments be exclusive?
Evidence reuses the existing `uploaded_files` table, which stores files in S3 (`s3_file_bucket` / `s3_file_key`) and records provenance via the `file_source` enum.
Open points: which `file_type` / `file_source` values Projects uploads should use (new enum values are likely needed), and whether the `project_workstream_id` column can eventually become NOT NULL for Projects-originated uploads.
A `"projects"` `file_source` value has been added. Open points: which `file_type` value(s) Projects uploads should use, and whether the `project_workstream_id` column can eventually become NOT NULL for Projects-originated uploads.
---