Compare commits

...

2 Commits

Author SHA1 Message Date
JCEEE 3085934fb9 fix pb migration 2026-08-10 15:56:03 +01:00
JCEEE e1fb046afd update dockerfile 2026-08-10 14:09:04 +01:00
6 changed files with 64 additions and 7 deletions
+30
View File
@@ -191,3 +191,33 @@
- Frontend: uses `kit.alias` in `vite.config.ts` (NOT `paths` in `frontend/tsconfig.json`, which SvelteKit warns against). Frontend imports shared files **without** the `.ts` extension (`@shared/timezone`) because `rewriteRelativeImportExtensions` only rewrites relative paths.
- Verified: proxy build + frontend build + `svelte-check` all clean for `@shared/*` (svelte-check still reports pre-existing `qrcode` types + CSS warnings).
- Docker note: runtime image only copies `frontend/build` + `proxy/dist` (both already bundle `shared/`), so `shared/` needn't be copied into the image.
### 2026-08-10 — Dev runtime cleanup (PB instances / containers)
- **Removed** test container `31e74178b3f0` (`famdone-service-app-1`, host :3010 + :8092). It ran **PB 0.39.10** and bound the **same host `pb_data`** as pb-dev → two PBs (v0.25 + v0.39) writing one SQLite DB = corruption/lock risk (likely source of dev instability/login lag).
- **Killed** 7 stale host `tsx watch` dev-proxy processes (Jul 28–Aug 5) + my throwaway 0.39 PBs.
- **Reset pb_data**: stopped pb-dev, wiped `/home/threejjjs/development/famchamp/pb_data`, **recreated** pb-dev container (fresh v0.25 store) with `--automigrate=false`, recreated dev superuser `debug@famchamp.dev`/`debug123`.
- **Why recreate pb-dev**: v0.25 automigrate had baked stale `pb_migrations` into the old container's writable layer; on a fresh store they failed (`Failed to apply migration ...: no rows in result set`).
- **Desired end state (confirmed)**: `8090` = pb-dev (v0.25, single instance, automigrate off); `3001`+`8091` = PROD app `cffd636cc772` (kept, not live); PROD pb_data at `/data/coolify/.../pb_data` (separate from dev).
### 2026-08-10 — PB 0.25 → 0.39 migration (branch `feature/migrate-pocketbase`)
- **Decision**: keep our own `migrate.ts` schema-as-code (API-driven, does data migrations + rule locking), NOT PocketBase's built-in automigrate (schema-only, generates version-specific migration files, and generates conflicting snapshots on upgraded stores). Disable PB automigrate in the runtime.
- **Verified against 0.39.10** (throwaway binaries on `127.0.0.1:8098/8099`, temp data dirs):
1. Fresh store: `migrate()` bootstraps all 14 `SCHEMA_PLAN` collections + every field migration cleanly (schema field builders are 0.39-compatible).
2. Existing 0.25 `pb_data` → 0.39: opens & serves with **`--automigrate=false`** and no stale `pb_migrations` dir. (Without this, automigrate writes a snapshot to `./pb_migrations` relative to CWD that conflicts with existing collections → "Collection name must be unique".)
3. JS SDK `pocketbase@^0.27.0`: `authWithPassword` + public reads OK; realtime SSE endpoint serves `PB_CONNECT`.
- **Code changes on branch**:
- `docker/Dockerfile` `POCKETBASE_VERSION` → `0.39.10`.
- `docker/Dockerfile.dev` → `0.39.10` + `CMD ... --automigrate=false`.
- `docker/entrypoint.sh` → `pocketbase serve ... --automigrate=false`.
- `proxy/src/env.ts` → added non-breaking `PB_ENDPOINT` env override (used to point migrate at a throwaway PB on another port; default dev/prod split unchanged).
- **⚠️ 0.39 schema breaking change**: PB 0.39 does **NOT** auto-add `createdAt`/`updatedAt` to **API-created** collections (0.25 did). The chat store filters/sorts on a custom `messages.createdAt`, so a fresh 0.39 store is missing it → raw PB 400. Fixed two ways:
- `shared/pb/schema.ts`: `messages` now declares `date("createdAt")` explicitly (source of truth → `ensureSchema`).
- `proxy/src/migrate.ts`: the "messages already exists" branch now adds `createdAt` if missing (idempotent hardening for drifted/upgraded stores).
- **Dev now on 0.39.10**: pb-dev rebuilt from branch `Dockerfile.dev` (0.39.10 + `--automigrate=false`), fresh store on :8090, superuser `debug@famchamp.dev` re-verified, `migrate()` bootstraps schema + applies `messages.createdAt` fix cleanly.
- **Prod upgrade steps**: backup `pb_data` → run the 0.39 image (automigrate off) → run `migrate()` → verify no drift (`messages.createdAt`, `id.autogeneratePattern`).
### 2026-08-10 — Revert PB to 0.25.8 (backtrack from 0.39)
- **Decision**: backtrack off the PocketBase 0.39 bump (introduced in commit `3725c54` via `ARG POCKETBASE_VERSION=0.39.10`) and work from a **0.25.8 baseline** in BOTH dev and prod, then migrate to 0.39 deliberately later.
- Reverted `docker/Dockerfile` `POCKETBASE_VERSION` back to `0.25.8` (matches `docker/Dockerfile.dev`). Dev `pb-dev` and the docker app internal PB `:8091` share host `./pb_data`.
- **Migration schema scripts (DO NOT FORGET)**: the schema single source of truth is `shared/pb/schema.ts` (`SCHEMA_PLAN`), iterated by `proxy/src/migrate.ts` (`ensureSchema`) and `proxy/scripts/seed.ts`. The chat `messages` / `chat_typing` collections are defined there **without** an explicit `createdAt` — they rely on PB auto-adding it on first create.
- The 0.39 prod `messages` drift (missing `createdAt`, then `id` "Cannot be blank" after a raw field PATCH) came from schema mismatch during the bump. When migrating 0.25→0.39, reconcile the schema scripts against 0.39's field semantics (incl. system `id` `autogeneratePattern`) instead of patching collections by hand.
+2 -2
View File
@@ -1,8 +1,8 @@
FROM alpine:latest
RUN apk add --no-cache curl unzip && \
curl -L -o /tmp/pb.zip https://github.com/pocketbase/pocketbase/releases/download/v0.25.8/pocketbase_0.25.8_linux_amd64.zip && \
curl -L -o /tmp/pb.zip https://github.com/pocketbase/pocketbase/releases/download/v0.39.10/pocketbase_0.39.10_linux_amd64.zip && \
unzip /tmp/pb.zip -d /usr/local/bin/ && \
rm /tmp/pb.zip && \
apk del curl unzip
EXPOSE 8090
CMD ["pocketbase", "serve", "--http=0.0.0.0:8090"]
CMD ["pocketbase", "serve", "--http=0.0.0.0:8090", "--automigrate=false"]
+3 -1
View File
@@ -12,7 +12,9 @@ if [ -n "$PB_EMAIL" ] && [ -n "$PB_PASSWORD" ]; then
fi
# Start PocketBase (internal only; published via loopback for admin UI).
pocketbase serve --http=0.0.0.0:8090 --dir="$PB_DATA" &
# --automigrate=false: we own schema via proxy migrate.ts; PB's built-in
# automigrate generates conflicting snapshots on upgraded stores.
pocketbase serve --http=0.0.0.0:8090 --dir="$PB_DATA" --automigrate=false &
# Wait for PB to be healthy before starting the proxy (which runs migrate).
echo "[entrypoint] Waiting for PocketBase..."
+5 -3
View File
@@ -7,8 +7,10 @@
// so SERVER_IP is unset → loopback below.
const SERVER_IP = process.env.SERVER_IP;
export const PB_ENDPOINT = SERVER_IP
? `http://${SERVER_IP}:8090`
: `http://127.0.0.1:8090`;
// PB_ENDPOINT can be overridden explicitly (used for migration step-through
// against a throwaway PB on another port). Defaults to the dev/prod split.
export const PB_ENDPOINT =
process.env.PB_ENDPOINT ||
(SERVER_IP ? `http://${SERVER_IP}:8090` : `http://127.0.0.1:8090`);
export const PB_EMAIL = process.env.PB_EMAIL || "debug@famchamp.dev";
export const PB_PASSWORD = process.env.PB_PASSWORD || "debug123";
+20
View File
@@ -1455,8 +1455,28 @@ export async function migrate(): Promise<void> {
});
} else {
console.log(` ↳ messages already exists`);
// PB 0.39 doesn't auto-add createdAt to API-created collections, and
// older stores may predate it. Chat filters/sorts on createdAt, so
// ensure the field exists even if the collection was created without it.
const msgsFields = msgsCol.fields?.map((f: any) => f.name) || [];
if (!msgsFields.includes("createdAt")) {
console.log(" ↳ adding missing createdAt field to messages...");
msgsCol.fields.push({
name: "createdAt",
type: "date",
required: false,
min: "",
max: "",
});
await updateCollection("messages", {
listRule: "",
viewRule: "",
fields: msgsCol.fields,
});
} else {
await updateCollection("messages", { listRule: "", viewRule: "" });
}
}
// 9b. chat_typing (transient presence rows, one per actor)
const typingCol = await getCollection("chat_typing");
+3
View File
@@ -219,6 +219,9 @@ export const SCHEMA_PLAN: CollectionPlanEntry[] = [
text("authorName", true),
text("authorColor"),
text("content", true),
// Explicit createdAt: PB 0.39 does NOT auto-add createdAt to
// API-created collections (0.25 did). Chat filters/sorts on it.
date("createdAt"),
])(ids),
},
{