Files
ballet-server/backend/internal/database/001_practice.sql
T
yuxuanhui 6224ef5980 feat: add growth tracking page and related functionality
- Implemented a new Growth page to track practice time and trends.
- Added API integration for fetching review data.
- Created components for displaying practice statistics and trends.
- Updated navigation titles for the main index and growth pages.
- Removed unused styles from the index page.
- Introduced a Projects management page for adding and editing practice projects.
- Developed a Record form for logging practice sessions with validation.
- Added utility functions for date manipulation and duration formatting.
- Implemented error handling and session management in the practice service.
- Created unit tests for the practice service to ensure reliability.
2026-09-29 13:47:26 +08:00

48 lines
1.7 KiB
SQL

CREATE TABLE users (
id text PRIMARY KEY,
wechat_identity text NOT NULL UNIQUE,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE sessions (
token_hash text PRIMARY KEY,
user_id text NOT NULL REFERENCES users(id),
expires_at timestamptz NOT NULL
);
CREATE INDEX sessions_expiry ON sessions(expires_at);
CREATE TABLE projects (
id text PRIMARY KEY,
user_id text NOT NULL REFERENCES users(id),
name text NOT NULL CHECK (char_length(btrim(name)) BETWEEN 1 AND 40),
archived boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
position bigint GENERATED ALWAYS AS IDENTITY,
UNIQUE (user_id, id)
);
CREATE INDEX projects_owner ON projects(user_id, position);
CREATE TABLE records (
id text PRIMARY KEY,
user_id text NOT NULL REFERENCES users(id),
project_id text NOT NULL,
practice_date date NOT NULL CHECK (practice_date >= DATE '0001-01-01'),
minutes integer NOT NULL CHECK (minutes > 0),
note text NOT NULL DEFAULT '' CHECK (char_length(note) <= 2000),
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
FOREIGN KEY (user_id, project_id) REFERENCES projects(user_id, id) ON DELETE RESTRICT
);
CREATE INDEX records_owner_date ON records(user_id, practice_date DESC, id DESC);
CREATE INDEX records_owner_updated ON records(user_id, updated_at DESC, id DESC);
CREATE INDEX records_project ON records(user_id, project_id);
-- Keep submission receipts after a record is deleted so a delayed retry cannot resurrect it.
CREATE TABLE submissions (
user_id text NOT NULL REFERENCES users(id),
request_id text NOT NULL,
payload_hash text NOT NULL,
record_id text NOT NULL,
PRIMARY KEY (user_id, request_id)
);