docs: add database documentation, migration registry, and setup guard for first admin registration
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# 0001 Initial Schema
|
||||
|
||||
SQL file: `supabase/schema.sql`
|
||||
|
||||
## Purpose
|
||||
|
||||
This is the first registered database query file for the project. It represents the schema that existed before the Freelancer OS MVP planning work started.
|
||||
|
||||
## What It Creates
|
||||
|
||||
- `journals`
|
||||
- `tasks`
|
||||
- `chat_sessions`
|
||||
- `chat_messages`
|
||||
- `profiles`
|
||||
- Row Level Security policies for the tables above
|
||||
- `handle_new_user()` trigger function for profile creation
|
||||
- `on_auth_user_created` trigger
|
||||
- `avatars` storage bucket and related storage policies
|
||||
|
||||
## Current Product Fit
|
||||
|
||||
This schema supports the earlier MindSpace/Cognis prototype:
|
||||
|
||||
- mood/energy journals
|
||||
- basic tasks
|
||||
- chat history
|
||||
- user profile storage
|
||||
- avatar uploads
|
||||
|
||||
It does not yet fully match the Freelancer OS MVP model.
|
||||
|
||||
## Known Gaps For MVP
|
||||
|
||||
The Freelancer OS MVP still needs new schema additions for:
|
||||
|
||||
- `clients`
|
||||
- `projects`
|
||||
- `calendar_events`
|
||||
- `finance_transactions`
|
||||
- `daily_logs`
|
||||
- `app_settings`
|
||||
|
||||
The existing `journals` table can either be migrated into `daily_logs` or kept as a legacy table until the UI is moved to the new model.
|
||||
|
||||
## Execution Notes
|
||||
|
||||
This file should be treated as the first baseline.
|
||||
|
||||
It was updated to be safer for Supabase SQL Editor retries:
|
||||
|
||||
- tables use `create table if not exists`
|
||||
- policies are dropped before being recreated
|
||||
- the profile trigger is dropped before being recreated
|
||||
- the PL/pgSQL function uses the correct `$$` delimiter
|
||||
- profile creation uses `on conflict (id) do nothing`
|
||||
|
||||
If a previous run failed halfway through, rerunning this baseline should be safe for the current schema shape.
|
||||
|
||||
Future changes should be added as ordered migration files rather than editing this baseline after execution.
|
||||
@@ -0,0 +1,72 @@
|
||||
# 0002 Freelancer OS Core Tables
|
||||
|
||||
SQL file: `supabase/migrations/0002_add_freelancer_os_core_tables.sql`
|
||||
|
||||
## Purpose
|
||||
|
||||
Adds the database model required for the Freelancer OS MVP.
|
||||
|
||||
This migration keeps the existing baseline from `supabase/schema.sql` and extends it instead of replacing it. The existing `tasks` table is reused and enriched with freelancer-specific fields.
|
||||
|
||||
## What It Creates
|
||||
|
||||
- `clients`
|
||||
- `projects`
|
||||
- `calendar_events`
|
||||
- `finance_transactions`
|
||||
- `daily_logs`
|
||||
- `app_settings`
|
||||
- `set_updated_at()` trigger function
|
||||
- updated-at triggers for the new tables
|
||||
- indexes for common dashboard/report queries
|
||||
- RLS policies for every new table
|
||||
|
||||
## What It Changes
|
||||
|
||||
The existing `tasks` table gets these additional columns:
|
||||
|
||||
- `client_id`
|
||||
- `project_id`
|
||||
- `priority`
|
||||
- `due_at`
|
||||
- `estimated_minutes`
|
||||
- `actual_minutes`
|
||||
|
||||
This lets a task belong to a client and/or project while preserving the earlier journal/task prototype schema.
|
||||
|
||||
## MVP Coverage
|
||||
|
||||
This migration supports:
|
||||
|
||||
- client management
|
||||
- client projects
|
||||
- side projects
|
||||
- task planning
|
||||
- calendar planning
|
||||
- income and expense tracking
|
||||
- daily mood/energy logging
|
||||
- app and AI provider settings
|
||||
|
||||
## RLS Model
|
||||
|
||||
Every new table has `user_id`.
|
||||
|
||||
Policies follow the same pattern:
|
||||
|
||||
- users can select their own rows
|
||||
- users can insert rows only for themselves
|
||||
- users can update their own rows
|
||||
- users can delete their own rows
|
||||
|
||||
## Notes
|
||||
|
||||
`app_settings.api_key` exists for compatibility with the current prototype flow. For production-grade use, provider credentials should be encrypted or moved to a safer secret-management strategy.
|
||||
|
||||
`daily_logs` is the new MVP-oriented replacement for the earlier `journals` concept. The old `journals` table remains available until the UI migration is complete.
|
||||
|
||||
## Execution
|
||||
|
||||
Run this after `supabase/schema.sql`.
|
||||
|
||||
Do not add this file to `query-log.md` until it has actually been executed against a database.
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
# 0003 - Project Planning Assets
|
||||
|
||||
SQL file: `supabase/migrations/0003_add_project_planning_assets.sql`
|
||||
|
||||
## Purpose
|
||||
|
||||
This migration extends project management beyond task tracking.
|
||||
|
||||
It adds:
|
||||
|
||||
- Project cover image fields on `projects`
|
||||
- A private Supabase Storage bucket for uploaded project images
|
||||
- A structured `project_planning_sections` table for project planning categories
|
||||
|
||||
## Project Image Fields
|
||||
|
||||
The `projects` table receives:
|
||||
|
||||
- `cover_image_path`: path of the uploaded file in the `project-assets` bucket
|
||||
- `cover_image_alt`: optional alt text for the cover image
|
||||
|
||||
Images are uploaded from the user's computer, not saved as external image links.
|
||||
|
||||
## Storage Bucket
|
||||
|
||||
Bucket:
|
||||
|
||||
- `project-assets`
|
||||
|
||||
Configuration:
|
||||
|
||||
- Private bucket
|
||||
- Max file size: 5 MB
|
||||
- Allowed MIME types:
|
||||
- `image/jpeg`
|
||||
- `image/png`
|
||||
- `image/webp`
|
||||
- `image/gif`
|
||||
|
||||
Storage object paths must start with the authenticated user id:
|
||||
|
||||
```txt
|
||||
<user_id>/projects/<project_id>/<file_name>
|
||||
```
|
||||
|
||||
This keeps Storage RLS simple and user-scoped.
|
||||
|
||||
## Planning Sections
|
||||
|
||||
Table:
|
||||
|
||||
- `project_planning_sections`
|
||||
|
||||
Core fields:
|
||||
|
||||
- `user_id`
|
||||
- `project_id`
|
||||
- `category`
|
||||
- `title`
|
||||
- `content`
|
||||
- `metadata`
|
||||
- `sort_order`
|
||||
|
||||
Allowed categories:
|
||||
|
||||
- `overview`
|
||||
- `problem`
|
||||
- `goal`
|
||||
- `audience`
|
||||
- `scope`
|
||||
- `design_system`
|
||||
- `color_palette`
|
||||
- `typography`
|
||||
- `assets`
|
||||
- `notes`
|
||||
|
||||
## RLS
|
||||
|
||||
RLS is enabled for `project_planning_sections`.
|
||||
|
||||
Users can only select, insert, update, and delete their own planning sections.
|
||||
|
||||
Storage policies allow users to select, upload, update, and delete only files under their own user id folder inside `project-assets`.
|
||||
|
||||
## Execution
|
||||
|
||||
Run after:
|
||||
|
||||
1. `supabase/schema.sql`
|
||||
2. `supabase/migrations/0002_add_freelancer_os_core_tables.sql`
|
||||
|
||||
After running this SQL in Supabase, add an execution record to `docs/database/query-log.md`.
|
||||
@@ -0,0 +1,34 @@
|
||||
# 0009 - Lock Registration After First Admin
|
||||
|
||||
SQL file:
|
||||
|
||||
`supabase/migrations/0009_lock_registration_after_first_admin.sql`
|
||||
|
||||
## Purpose
|
||||
|
||||
Adds the first-time setup guard for self-hosted installations.
|
||||
|
||||
The `/register` page is only available while the system has no profile record. After the first account creates a profile, public registration is closed.
|
||||
|
||||
## Changes
|
||||
|
||||
- Adds `public.is_first_admin_setup_available()`.
|
||||
- Grants the function to `anon` and `authenticated` roles so the app can check setup state safely without bypassing RLS manually.
|
||||
- Replaces `public.handle_new_user()` so direct public Supabase Auth signup attempts are also rejected after the first profile exists.
|
||||
- Allows service-role/admin-created users when `raw_app_meta_data.internal_created` is `true`, so future invite/client-portal flows can still create accounts intentionally.
|
||||
|
||||
## Behavior
|
||||
|
||||
1. Fresh install has no `public.profiles` rows.
|
||||
2. `/register` stays open.
|
||||
3. The first signup creates an auth user and the trigger creates the first profile.
|
||||
4. The setup function starts returning `false`.
|
||||
5. `/register` redirects to `/login`.
|
||||
6. Further public signup attempts fail at the database trigger level.
|
||||
7. Admin-created internal users can still be allowed by service-role flows that set `app_metadata.internal_created = true`.
|
||||
|
||||
## Notes
|
||||
|
||||
- This is intended for the MVP single-admin self-host model.
|
||||
- If multi-user, client portal accounts, invites, or team members are re-enabled later, keep them behind service-role/admin-created flows instead of public signup.
|
||||
- Do not add this SQL file to `query-log.md` until it has actually been run in the target Supabase environment.
|
||||
@@ -0,0 +1,44 @@
|
||||
# Database Change Process
|
||||
|
||||
This directory records every database change that should be run against Supabase/PostgreSQL.
|
||||
|
||||
The project currently starts with `supabase/schema.sql` as the first database query file. Future database changes must be added as separate SQL files and registered here before they are run.
|
||||
|
||||
## Rules
|
||||
|
||||
1. Every SQL change must have a stable order number.
|
||||
2. Every SQL file must be listed in `query-order.md`.
|
||||
3. Every executed query must be recorded in `query-log.md`.
|
||||
4. Every meaningful schema addition must have a short documentation file under this directory.
|
||||
5. Do not edit an already executed SQL file silently. Add a new ordered SQL file instead.
|
||||
|
||||
## Current Files
|
||||
|
||||
- `supabase/schema.sql`: Initial legacy schema. It creates the current auth/profile, journal, task, chat, and avatar storage structure.
|
||||
- `supabase/migrations/0002_add_freelancer_os_core_tables.sql`: Freelancer OS MVP core schema.
|
||||
- `supabase/seeds/0001_demo_freelancer_os_data.sql`: Optional local/demo data for the MVP schema.
|
||||
- `docs/database/0001-initial-schema.md`: Explanation for the initial schema.
|
||||
- `docs/database/0002-freelancer-os-core-tables.md`: Explanation for the MVP schema migration.
|
||||
- `docs/database/seed-0001-demo-freelancer-os-data.md`: Explanation for the demo seed file.
|
||||
- `docs/database/query-order.md`: Canonical order of SQL files.
|
||||
- `docs/database/query-log.md`: Manual execution log for SQL files that were run against an environment.
|
||||
|
||||
## Next Migration Naming
|
||||
|
||||
Use this pattern for future SQL files:
|
||||
|
||||
```text
|
||||
supabase/migrations/0002_short_description.sql
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
supabase/migrations/0002_add_freelancer_os_core_tables.sql
|
||||
```
|
||||
|
||||
Use this pattern for future seed files:
|
||||
|
||||
```text
|
||||
supabase/seeds/0002_short_description.sql
|
||||
```
|
||||
@@ -0,0 +1,10 @@
|
||||
# Database Query Log
|
||||
|
||||
This file records SQL files that were executed against a database environment.
|
||||
|
||||
Do not mark a query as executed unless it was actually run.
|
||||
|
||||
| Date | Environment | Order | SQL file | Runner | Result | Notes |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| Not recorded | Unknown existing environment | 0001 | `supabase/schema.sql` | Unknown | Assumed existing baseline | File existed before this query log was introduced. Confirm manually before rerunning. |
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# Database Query Order
|
||||
|
||||
This file is the canonical order of SQL files for database setup and migration.
|
||||
|
||||
| Order | SQL file | Documentation | Status |
|
||||
| --- | --- | --- | --- |
|
||||
| 0001 | `supabase/schema.sql` | `docs/database/0001-initial-schema.md` | Baseline registered |
|
||||
| 0002 | `supabase/migrations/0002_add_freelancer_os_core_tables.sql` | `docs/database/0002-freelancer-os-core-tables.md` | Pending execution |
|
||||
| 0003 | `supabase/migrations/0003_add_project_planning_assets.sql` | `docs/database/0003-project-planning-assets.md` | Pending execution |
|
||||
| 0009 | `supabase/migrations/0009_lock_registration_after_first_admin.sql` | `docs/database/0009-lock-registration-after-first-admin.md` | Pending execution |
|
||||
| seed-0001 | `supabase/seeds/0001_demo_freelancer_os_data.sql` | `docs/database/seed-0001-demo-freelancer-os-data.md` | Optional demo seed, pending execution |
|
||||
|
||||
## How To Add The Next Query
|
||||
|
||||
1. Create a new SQL file under `supabase/migrations/`.
|
||||
2. Use the next order number.
|
||||
3. Add a documentation file under `docs/database/`.
|
||||
4. Register both files in this table.
|
||||
5. After running the SQL, add an entry to `query-log.md`.
|
||||
|
||||
## Seed Files
|
||||
|
||||
Seed files are optional and should live under `supabase/seeds/`.
|
||||
|
||||
They must also be documented and registered in this file, but they should only be run in local/demo environments unless explicitly approved.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Seed 0001 Demo Freelancer OS Data
|
||||
|
||||
SQL file: `supabase/seeds/0001_demo_freelancer_os_data.sql`
|
||||
|
||||
## Purpose
|
||||
|
||||
Adds demo data for local development and dashboard testing after the Freelancer OS core tables are created.
|
||||
|
||||
## What It Inserts
|
||||
|
||||
- demo clients
|
||||
- demo projects and one side project
|
||||
- demo tasks
|
||||
- demo calendar events
|
||||
- demo finance transactions
|
||||
- demo daily mood/energy logs
|
||||
- demo `app_settings`
|
||||
|
||||
## Required Manual Step
|
||||
|
||||
Before running the file, replace this placeholder with a real `auth.users.id`:
|
||||
|
||||
```sql
|
||||
'00000000-0000-0000-0000-000000000000'::uuid
|
||||
```
|
||||
|
||||
Use a user id from your Supabase Auth users table.
|
||||
|
||||
## Environment
|
||||
|
||||
This seed is intended for local and demo environments only.
|
||||
|
||||
Do not run it on production data.
|
||||
|
||||
## Execution
|
||||
|
||||
Run after:
|
||||
|
||||
1. `supabase/schema.sql`
|
||||
2. `supabase/migrations/0002_add_freelancer_os_core_tables.sql`
|
||||
|
||||
After running it, add an entry to `docs/database/query-log.md`.
|
||||
|
||||
Reference in New Issue
Block a user