fix pb migration
This commit is contained in:
@@ -192,6 +192,30 @@
|
|||||||
- Verified: proxy build + frontend build + `svelte-check` all clean for `@shared/*` (svelte-check still reports pre-existing `qrcode` types + CSS warnings).
|
- 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.
|
- 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)
|
### 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.
|
- **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`.
|
- 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`.
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ COPY --from=builder /app/proxy/dist ./proxy
|
|||||||
COPY docker/nginx.conf /etc/nginx/http.d/default.conf
|
COPY docker/nginx.conf /etc/nginx/http.d/default.conf
|
||||||
COPY docker/entrypoint.sh /entrypoint.sh
|
COPY docker/entrypoint.sh /entrypoint.sh
|
||||||
|
|
||||||
ARG POCKETBASE_VERSION=0.25.8
|
ARG POCKETBASE_VERSION=0.39.10
|
||||||
|
|
||||||
RUN wget -qO /tmp/pb.zip \
|
RUN wget -qO /tmp/pb.zip \
|
||||||
"https://github.com/pocketbase/pocketbase/releases/download/v${POCKETBASE_VERSION}/pocketbase_${POCKETBASE_VERSION}_linux_amd64.zip" \
|
"https://github.com/pocketbase/pocketbase/releases/download/v${POCKETBASE_VERSION}/pocketbase_${POCKETBASE_VERSION}_linux_amd64.zip" \
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
RUN apk add --no-cache curl unzip && \
|
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/ && \
|
unzip /tmp/pb.zip -d /usr/local/bin/ && \
|
||||||
rm /tmp/pb.zip && \
|
rm /tmp/pb.zip && \
|
||||||
apk del curl unzip
|
apk del curl unzip
|
||||||
EXPOSE 8090
|
EXPOSE 8090
|
||||||
CMD ["pocketbase", "serve", "--http=0.0.0.0:8090"]
|
CMD ["pocketbase", "serve", "--http=0.0.0.0:8090", "--automigrate=false"]
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ if [ -n "$PB_EMAIL" ] && [ -n "$PB_PASSWORD" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Start PocketBase (internal only; published via loopback for admin UI).
|
# 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).
|
# Wait for PB to be healthy before starting the proxy (which runs migrate).
|
||||||
echo "[entrypoint] Waiting for PocketBase..."
|
echo "[entrypoint] Waiting for PocketBase..."
|
||||||
|
|||||||
+5
-3
@@ -7,8 +7,10 @@
|
|||||||
// so SERVER_IP is unset → loopback below.
|
// so SERVER_IP is unset → loopback below.
|
||||||
const SERVER_IP = process.env.SERVER_IP;
|
const SERVER_IP = process.env.SERVER_IP;
|
||||||
|
|
||||||
export const PB_ENDPOINT = SERVER_IP
|
// PB_ENDPOINT can be overridden explicitly (used for migration step-through
|
||||||
? `http://${SERVER_IP}:8090`
|
// against a throwaway PB on another port). Defaults to the dev/prod split.
|
||||||
: `http://127.0.0.1:8090`;
|
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_EMAIL = process.env.PB_EMAIL || "debug@famchamp.dev";
|
||||||
export const PB_PASSWORD = process.env.PB_PASSWORD || "debug123";
|
export const PB_PASSWORD = process.env.PB_PASSWORD || "debug123";
|
||||||
|
|||||||
@@ -1455,8 +1455,28 @@ export async function migrate(): Promise<void> {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log(` ↳ messages already exists`);
|
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: "" });
|
await updateCollection("messages", { listRule: "", viewRule: "" });
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 9b. chat_typing (transient presence rows, one per actor)
|
// 9b. chat_typing (transient presence rows, one per actor)
|
||||||
const typingCol = await getCollection("chat_typing");
|
const typingCol = await getCollection("chat_typing");
|
||||||
|
|||||||
@@ -219,6 +219,9 @@ export const SCHEMA_PLAN: CollectionPlanEntry[] = [
|
|||||||
text("authorName", true),
|
text("authorName", true),
|
||||||
text("authorColor"),
|
text("authorColor"),
|
||||||
text("content", true),
|
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),
|
])(ids),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user