2 Commits

Author SHA1 Message Date
KS Jannette
0b56d0d6c4 further DB infra buildout 2026-02-24 19:38:35 -05:00
S Jannette
0d22998c2e Merge pull request #14 from kjannette/db-build
db created, added tests -- tentative
2026-02-24 19:26:55 -05:00
3 changed files with 183 additions and 407 deletions

View File

@@ -1,402 +0,0 @@
[
{
"id": "note_038",
"text": "Live follow mode frequently breaks",
"x": 710,
"y": 579,
"author": "user_9",
"color": "yellow"
},
{
"id": "note_005",
"text": "SSO login loops back to the sign-in page",
"x": 184,
"y": 124,
"author": "user_7",
"color": "yellow"
},
{
"id": "note_023",
"text": "Undo/redo sometimes lags and applies late",
"x": 236,
"y": 687,
"author": "user_9",
"color": "purple"
},
{
"id": "note_017",
"text": "Exported file names are inconsistent and hard to track",
"x": 676,
"y": 201,
"author": "user_4",
"color": "blue"
},
{
"id": "note_049",
"text": "Need better controls for aligning and distributing notes",
"x": 462,
"y": 487,
"author": "user_7",
"color": "green"
},
{
"id": "note_010",
"text": "OAuth consent screen appears every time I sign in",
"x": 228,
"y": 124,
"author": "user_9",
"color": "yellow"
},
{
"id": "note_036",
"text": "Cursor presence is distracting and overlaps content",
"x": 788,
"y": 605,
"author": "user_5",
"color": "yellow"
},
{
"id": "note_011",
"text": "Need better export options (PDF quality is too low)",
"x": 748,
"y": 212,
"author": "user_9",
"color": "green"
},
{
"id": "note_012",
"text": "Exported PDF cuts off content near the edges",
"x": 733,
"y": 159,
"author": "user_6",
"color": "blue"
},
{
"id": "note_019",
"text": "Embedded exports dont update when the board changes",
"x": 662,
"y": 132,
"author": "user_1",
"color": "blue"
},
{
"id": "note_020",
"text": "Cant export comments and reactions with the content",
"x": 739,
"y": 139,
"author": "user_7",
"color": "green"
},
{
"id": "note_039",
"text": "Guest collaborators cant see updates without refreshing",
"x": 759,
"y": 711,
"author": "user_9",
"color": "yellow"
},
{
"id": "note_024",
"text": "App crashes when opening a large board",
"x": 239,
"y": 597,
"author": "user_10",
"color": "purple"
},
{
"id": "note_041",
"text": "Hard to find the right template quickly",
"x": 536,
"y": 394,
"author": "user_4",
"color": "orange"
},
{
"id": "note_040",
"text": "Activity feed lacks context about what changed",
"x": 710,
"y": 771,
"author": "user_7",
"color": "yellow"
},
{
"id": "note_014",
"text": "Export takes too long and sometimes never finishes",
"x": 798,
"y": 211,
"author": "user_2",
"color": "green"
},
{
"id": "note_031",
"text": "Hard to tell who is editing what in real time",
"x": 761,
"y": 704,
"author": "user_8",
"color": "yellow"
},
{
"id": "note_032",
"text": "Comments get lost — no clear thread view",
"x": 818,
"y": 641,
"author": "user_5",
"color": "yellow"
},
{
"id": "note_050",
"text": "Cant lock sections to prevent accidental edits during workshops",
"x": 521,
"y": 471,
"author": "user_6",
"color": "orange"
},
{
"id": "note_001",
"text": "Login flow feels confusing",
"x": 193,
"y": 191,
"author": "user_5",
"color": "yellow"
},
{
"id": "note_025",
"text": "Saving indicator spins but changes arent saved",
"x": 129,
"y": 781,
"author": "user_3",
"color": "purple"
},
{
"id": "note_021",
"text": "Board feels slow when there are many sticky notes",
"x": 341,
"y": 695,
"author": "user_10",
"color": "purple"
},
{
"id": "note_002",
"text": "Login flow is broken on mobile",
"x": 214,
"y": 281,
"author": "user_9",
"color": "yellow"
},
{
"id": "note_046",
"text": "Tags are missing — I need better categorization",
"x": 472,
"y": 435,
"author": "user_6",
"color": "green"
},
{
"id": "note_018",
"text": "No way to schedule recurring exports for stakeholders",
"x": 661,
"y": 229,
"author": "user_9",
"color": "blue"
},
{
"id": "note_034",
"text": "Too many notification emails for minor edits",
"x": 769,
"y": 739,
"author": "user_9",
"color": "yellow"
},
{
"id": "note_003",
"text": "When I enter my username and password I get an unknown error",
"x": 189,
"y": 193,
"author": "user_2",
"color": "yellow"
},
{
"id": "note_008",
"text": "Cannot change my password — save button does nothing",
"x": 244,
"y": 188,
"author": "user_2",
"color": "orange"
},
{
"id": "note_015",
"text": "Sharing link permissions are confusing",
"x": 688,
"y": 290,
"author": "user_6",
"color": "blue"
},
{
"id": "note_033",
"text": "Mentions (@) dont notify the right people",
"x": 696,
"y": 669,
"author": "user_5",
"color": "yellow"
},
{
"id": "note_006",
"text": "Two-factor code is rejected even when correct",
"x": 162,
"y": 213,
"author": "user_1",
"color": "yellow"
},
{
"id": "note_028",
"text": "High CPU usage even when idle on a board",
"x": 190,
"y": 695,
"author": "user_8",
"color": "purple"
},
{
"id": "note_009",
"text": "Account gets locked too quickly after one failed attempt",
"x": 280,
"y": 255,
"author": "user_10",
"color": "orange"
},
{
"id": "note_029",
"text": "Offline mode loses edits when reconnecting",
"x": 338,
"y": 632,
"author": "user_1",
"color": "pink"
},
{
"id": "note_035",
"text": "No notification when someone resolves my comment",
"x": 673,
"y": 636,
"author": "user_2",
"color": "blue"
},
{
"id": "note_037",
"text": "Cant easily hand off facilitation to another user",
"x": 816,
"y": 707,
"author": "user_2",
"color": "yellow"
},
{
"id": "note_013",
"text": "Cannot export selected area — only full board exports",
"x": 696,
"y": 205,
"author": "user_4",
"color": "green"
},
{
"id": "note_016",
"text": "Downloaded image is blurry compared to the canvas",
"x": 677,
"y": 245,
"author": "user_5",
"color": "blue"
},
{
"id": "note_043",
"text": "Cant organize boards into folders the way I need",
"x": 504,
"y": 398,
"author": "user_4",
"color": "green"
},
{
"id": "note_022",
"text": "Canvas freezes for a few seconds when zooming",
"x": 254,
"y": 707,
"author": "user_8",
"color": "pink"
},
{
"id": "note_026",
"text": "Search is slow on boards with lots of content",
"x": 253,
"y": 658,
"author": "user_2",
"color": "pink"
},
{
"id": "note_048",
"text": "Duplicating a board loses some formatting",
"x": 382,
"y": 410,
"author": "user_10",
"color": "orange"
},
{
"id": "note_007",
"text": "Im logged out unexpectedly after a few minutes",
"x": 185,
"y": 157,
"author": "user_3",
"color": "yellow"
},
{
"id": "note_045",
"text": "No bulk rename for multiple sticky notes",
"x": 455,
"y": 427,
"author": "user_1",
"color": "green"
},
{
"id": "note_042",
"text": "Template search results feel irrelevant",
"x": 400,
"y": 474,
"author": "user_6",
"color": "orange"
},
{
"id": "note_044",
"text": "Naming conventions arent enforced and things get messy",
"x": 469,
"y": 434,
"author": "user_9",
"color": "green"
},
{
"id": "note_004",
"text": "Password reset email never arrives",
"x": 207,
"y": 267,
"author": "user_9",
"color": "yellow"
},
{
"id": "note_047",
"text": "Hard to keep consistent styles across boards",
"x": 420,
"y": 426,
"author": "user_8",
"color": "green"
},
{
"id": "note_030",
"text": "I see random 'something went wrong' banners with no details",
"x": 214,
"y": 594,
"author": "user_5",
"color": "purple"
},
{
"id": "note_027",
"text": "Scrolling stutters on older laptops",
"x": 178,
"y": 586,
"author": "user_7",
"color": "pink"
}
]

131
backend/db/README.md Normal file
View File

@@ -0,0 +1,131 @@
# Database — kongruity backend
PostgreSQL database layer for the kongruity backend. All database modules live in this directory.
## Prerequisites
- PostgreSQL v14 or later
- The `DATABASE_URL` environment variable set in `backend/.env`
## Configuration
### Environment variable
The connection pool reads a single env var:
```
DATABASE_URL=postgresql://<user>:<password>@localhost:5432/kongruity
```
This is loaded via `dotenv` from `backend/.env` (git-ignored). The pool is created once in `index.js` and shared across the application.
### Connection pool (`index.js`)
| Export | Description |
|-------------|--------------------------------------------------|
| `query` | Execute a parameterized SQL statement |
| `getPool` | Return the underlying `pg.Pool` instance |
| `close` | Gracefully shut down the pool (`pool.end()`) |
| `default` | The pool itself (default export) |
## Schema
### `notes` table
Created by the migration in `migrate.js`. The DDL is idempotent (`CREATE TABLE IF NOT EXISTS`).
| Column | Type | Constraints / Defaults |
|---------------|----------------|------------------------------|
| `id` | `VARCHAR(64)` | `PRIMARY KEY` |
| `text` | `TEXT` | `NOT NULL` |
| `x` | `INTEGER` | `DEFAULT 0` |
| `y` | `INTEGER` | `DEFAULT 0` |
| `author` | `VARCHAR(128)` | |
| `color` | `VARCHAR(32)` | `DEFAULT 'yellow'` |
| `source_meta` | `JSONB` | `DEFAULT '{}'` |
| `created_at` | `TIMESTAMPTZ` | `DEFAULT NOW()` |
| `updated_at` | `TIMESTAMPTZ` | `DEFAULT NOW()` |
## npm scripts
Run these from the `backend/` directory.
### Migrate
Creates the `notes` table (safe to re-run):
```bash
npm run db:migrate
```
### Seed
Inserts 50 sample sticky notes. Uses `ON CONFLICT (id) DO NOTHING`, so re-running is safe and will not duplicate data:
```bash
npm run db:seed
```
## Data access layer (`notes.dao.js`)
| Function | Description |
|---------------------------|--------------------------------------------------------------------|
| `getAllNotes()` | Returns all notes ordered by `id` |
| `getNoteById(id)` | Returns a single note by primary key, or `null` if not found |
| `createNote(note)` | Inserts one note and returns the created row |
| `createNotes(notes)` | Bulk-inserts an array of notes in a single query and returns rows |
All functions return plain objects with columns: `id`, `text`, `x`, `y`, `author`, `color`.
## File overview
```
db/
├── index.js # Connection pool and query helper
├── migrate.js # Table creation (run via npm run db:migrate)
├── notes.dao.js # Data access functions for the notes table
├── seed.js # Sample data seeder (run via npm run db:seed)
└── README.md # This file
```
## Useful psql commands
Connect to the database:
```bash
psql kongruity
```
Quick checks:
```sql
-- Row count
SELECT count(*) FROM notes;
-- Preview data
SELECT id, text, color FROM notes LIMIT 10;
-- Full schema info
\d notes
-- Drop and re-seed (destructive)
TRUNCATE notes;
```
Then re-seed:
```bash
npm run db:seed
```
## Resetting the database
To start completely fresh:
```bash
dropdb kongruity
createdb kongruity
cd backend
npm run db:migrate
npm run db:seed
```

View File

@@ -1,14 +1,61 @@
import 'dotenv/config';
import { readFile } from 'fs/promises';
import { query, close } from './index.js';
const NOTES_PATH = new URL('../data/notes.json', import.meta.url);
const notes = [
{ id: 'note_001', text: 'Login flow feels confusing', x: 193, y: 191, author: 'user_5', color: 'yellow' },
{ id: 'note_002', text: 'Login flow is broken on mobile', x: 214, y: 281, author: 'user_9', color: 'yellow' },
{ id: 'note_003', text: 'When I enter my username and password I get an unknown error', x: 189, y: 193, author: 'user_2', color: 'yellow' },
{ id: 'note_004', text: 'Password reset email never arrives', x: 207, y: 267, author: 'user_9', color: 'yellow' },
{ id: 'note_005', text: 'SSO login loops back to the sign-in page', x: 184, y: 124, author: 'user_7', color: 'yellow' },
{ id: 'note_006', text: 'Two-factor code is rejected even when correct', x: 162, y: 213, author: 'user_1', color: 'yellow' },
{ id: 'note_007', text: "I'm logged out unexpectedly after a few minutes", x: 185, y: 157, author: 'user_3', color: 'yellow' },
{ id: 'note_008', text: 'Cannot change my password — save button does nothing', x: 244, y: 188, author: 'user_2', color: 'orange' },
{ id: 'note_009', text: 'Account gets locked too quickly after one failed attempt', x: 280, y: 255, author: 'user_10', color: 'orange' },
{ id: 'note_010', text: 'OAuth consent screen appears every time I sign in', x: 228, y: 124, author: 'user_9', color: 'yellow' },
{ id: 'note_011', text: 'Need better export options (PDF quality is too low)', x: 748, y: 212, author: 'user_9', color: 'green' },
{ id: 'note_012', text: 'Exported PDF cuts off content near the edges', x: 733, y: 159, author: 'user_6', color: 'blue' },
{ id: 'note_013', text: 'Cannot export selected area — only full board exports', x: 696, y: 205, author: 'user_4', color: 'green' },
{ id: 'note_014', text: 'Export takes too long and sometimes never finishes', x: 798, y: 211, author: 'user_2', color: 'green' },
{ id: 'note_015', text: 'Sharing link permissions are confusing', x: 688, y: 290, author: 'user_6', color: 'blue' },
{ id: 'note_016', text: 'Downloaded image is blurry compared to the canvas', x: 677, y: 245, author: 'user_5', color: 'blue' },
{ id: 'note_017', text: 'Exported file names are inconsistent and hard to track', x: 676, y: 201, author: 'user_4', color: 'blue' },
{ id: 'note_018', text: 'No way to schedule recurring exports for stakeholders', x: 661, y: 229, author: 'user_9', color: 'blue' },
{ id: 'note_019', text: "Embedded exports don't update when the board changes", x: 662, y: 132, author: 'user_1', color: 'blue' },
{ id: 'note_020', text: "Can't export comments and reactions with the content", x: 739, y: 139, author: 'user_7', color: 'green' },
{ id: 'note_021', text: 'Board feels slow when there are many sticky notes', x: 341, y: 695, author: 'user_10', color: 'purple' },
{ id: 'note_022', text: 'Canvas freezes for a few seconds when zooming', x: 254, y: 707, author: 'user_8', color: 'pink' },
{ id: 'note_023', text: 'Undo/redo sometimes lags and applies late', x: 236, y: 687, author: 'user_9', color: 'purple' },
{ id: 'note_024', text: 'App crashes when opening a large board', x: 239, y: 597, author: 'user_10', color: 'purple' },
{ id: 'note_025', text: "Saving indicator spins but changes aren't saved", x: 129, y: 781, author: 'user_3', color: 'purple' },
{ id: 'note_026', text: 'Search is slow on boards with lots of content', x: 253, y: 658, author: 'user_2', color: 'pink' },
{ id: 'note_027', text: 'Scrolling stutters on older laptops', x: 178, y: 586, author: 'user_7', color: 'pink' },
{ id: 'note_028', text: 'High CPU usage even when idle on a board', x: 190, y: 695, author: 'user_8', color: 'purple' },
{ id: 'note_029', text: 'Offline mode loses edits when reconnecting', x: 338, y: 632, author: 'user_1', color: 'pink' },
{ id: 'note_030', text: "I see random 'something went wrong' banners with no details", x: 214, y: 594, author: 'user_5', color: 'purple' },
{ id: 'note_031', text: 'Hard to tell who is editing what in real time', x: 761, y: 704, author: 'user_8', color: 'yellow' },
{ id: 'note_032', text: 'Comments get lost — no clear thread view', x: 818, y: 641, author: 'user_5', color: 'yellow' },
{ id: 'note_033', text: "Mentions (@) don't notify the right people", x: 696, y: 669, author: 'user_5', color: 'yellow' },
{ id: 'note_034', text: 'Too many notification emails for minor edits', x: 769, y: 739, author: 'user_9', color: 'yellow' },
{ id: 'note_035', text: 'No notification when someone resolves my comment', x: 673, y: 636, author: 'user_2', color: 'blue' },
{ id: 'note_036', text: 'Cursor presence is distracting and overlaps content', x: 788, y: 605, author: 'user_5', color: 'yellow' },
{ id: 'note_037', text: "Can't easily hand off facilitation to another user", x: 816, y: 707, author: 'user_2', color: 'yellow' },
{ id: 'note_038', text: 'Live follow mode frequently breaks', x: 710, y: 579, author: 'user_9', color: 'yellow' },
{ id: 'note_039', text: "Guest collaborators can't see updates without refreshing", x: 759, y: 711, author: 'user_9', color: 'yellow' },
{ id: 'note_040', text: 'Activity feed lacks context about what changed', x: 710, y: 771, author: 'user_7', color: 'yellow' },
{ id: 'note_041', text: 'Hard to find the right template quickly', x: 536, y: 394, author: 'user_4', color: 'orange' },
{ id: 'note_042', text: 'Template search results feel irrelevant', x: 400, y: 474, author: 'user_6', color: 'orange' },
{ id: 'note_043', text: "Can't organize boards into folders the way I need", x: 504, y: 398, author: 'user_4', color: 'green' },
{ id: 'note_044', text: "Naming conventions aren't enforced and things get messy", x: 469, y: 434, author: 'user_9', color: 'green' },
{ id: 'note_045', text: 'No bulk rename for multiple sticky notes', x: 455, y: 427, author: 'user_1', color: 'green' },
{ id: 'note_046', text: 'Tags are missing — I need better categorization', x: 472, y: 435, author: 'user_6', color: 'green' },
{ id: 'note_047', text: 'Hard to keep consistent styles across boards', x: 420, y: 426, author: 'user_8', color: 'green' },
{ id: 'note_048', text: 'Duplicating a board loses some formatting', x: 382, y: 410, author: 'user_10', color: 'orange' },
{ id: 'note_049', text: 'Need better controls for aligning and distributing notes', x: 462, y: 487, author: 'user_7', color: 'green' },
{ id: 'note_050', text: "Can't lock sections to prevent accidental edits during workshops", x: 521, y: 471, author: 'user_6', color: 'orange' },
];
const run = async () => {
try {
const raw = await readFile(NOTES_PATH, 'utf-8');
const notes = JSON.parse(raw);
const insertQuery = `
INSERT INTO notes (id, text, x, y, author, color)
VALUES ($1, $2, $3, $4, $5, $6)