# Demo branch setup (`debrand`) This branch is a white-label demo. It uses a separate database, `fpsms_demo`, filled with fictional data. It must not read or write the live company database `fpsmsdb`, and it must not call the live M18 system. Check out `debrand` in both repositories: - `FPSMS-backend` - `FPSMS-frontend` Do not merge this branch. Do not start it with `db-local`, `prod`, or `db-toa`. ## What you get | | | | -------------- | --------------------------------------------------------------- | | Site | Frontend on port 3000, API on port 8090 | | Spring profile | `db-demo` | | Database | `fpsms_demo` on `127.0.0.1:3306` | | App login | `demo` / `Demo2026!` | | Also | `demo.stock` / `Demo2026!` (倉務), `demo.prod` / `Demo2026!` (出品) | `demo` has ADMIN, STOCK, PROD, PACK, and REPORT_MGMT. The UI language switch still works. Item names and other master data are stored in Chinese. On the report page, leave the dates empty for most downloads. For 「庫存盤點報告」 choose round 「示範盤點輪次」. For 「送貨訂單與倉存單位不符報告」 use today’s date. ## 1. Stop anything already on port 8090 The frontend on this branch calls `http://localhost:8090/api`. If a normal backend is already listening there, it is the live database. Stop that process before starting the demo. ## 2. Copy the table structure into `fpsms_demo` Liquibase changesets in this repo name the schema `fpsmsdb`. Running them against an empty database, as `root`, would change the live database. Do not do that. Use the local `root` account from `application-db-local.yml` only for this one-time copy. Create an empty schema, load the structure (no rows), then copy the Liquibase history so startup treats the schema as already up to date. ```bash mysql -h127.0.0.1 -P3306 -uroot -p -e \ "CREATE DATABASE IF NOT EXISTS fpsms_demo CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" mysqldump --no-data --routines --triggers -h127.0.0.1 -P3306 -uroot -p fpsmsdb \ > /tmp/fpsms_demo_schema.sql mysql -h127.0.0.1 -P3306 -uroot -p fpsms_demo < /tmp/fpsms_demo_schema.sql mysqldump -h127.0.0.1 -P3306 -uroot -p fpsmsdb DATABASECHANGELOG DATABASECHANGELOGLOCK \ > /tmp/fpsms_demo_changelog.sql mysql -h127.0.0.1 -P3306 -uroot -p fpsms_demo < /tmp/fpsms_demo_changelog.sql ``` `fpsms_demo` should now have tables and Liquibase history, and no company rows. ## 3. Create a login that cannot see `fpsmsdb` `application-db-demo.yml` connects as `fpsms_demo` / `FpsmsDemoOnly2026`. That account is allowed to use `fpsms_demo` only. ```bash mysql -h127.0.0.1 -P3306 -uroot -p <<'SQL' CREATE USER IF NOT EXISTS 'fpsms_demo'@'127.0.0.1' IDENTIFIED BY 'FpsmsDemoOnly2026'; CREATE USER IF NOT EXISTS 'fpsms_demo'@'localhost' IDENTIFIED BY 'FpsmsDemoOnly2026'; ALTER USER 'fpsms_demo'@'127.0.0.1' IDENTIFIED BY 'FpsmsDemoOnly2026'; ALTER USER 'fpsms_demo'@'localhost' IDENTIFIED BY 'FpsmsDemoOnly2026'; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON fpsms_demo.* TO 'fpsms_demo'@'127.0.0.1'; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON fpsms_demo.* TO 'fpsms_demo'@'localhost'; FLUSH PRIVILEGES; SQL ``` Confirm the wall before starting the app. The first command must fail with MySQL error 1142. The second must succeed. ```bash mysql -h127.0.0.1 -P3306 -ufpsms_demo -pFpsmsDemoOnly2026 -e "SELECT COUNT(*) FROM fpsmsdb.user;" mysql -h127.0.0.1 -P3306 -ufpsms_demo -pFpsmsDemoOnly2026 -D fpsms_demo -e "SELECT COUNT(*) FROM user;" ``` Do not put `root` back into `application-db-demo.yml`. If this login can read `fpsmsdb`, the demo profile refuses to start. That refusal is the point. ## 4. Start the backend JDK 17. From `FPSMS-backend`, on branch `debrand`: ```bash ./gradlew bootRun --args='--spring.profiles.active=db-demo' ``` The first boot inserts the fictional sandbox (`DemoSandboxSeeder`) and the extra report rows (`src/main/resources/demo/demo-coverage.sql`). Later boots skip both when user `demo` and setting `DEMO.coverage.v1` already exist. `DemoDateKeeper` then keeps those sample dates current. It runs at startup, every day at 00:10, and when the truck board is opened. It moves `DEMO-` expiry, delivery, order, pick, job, and stock-take dates forward by the number of days since the last run (stored as setting `DEMO.dates.anchor`). Lots stay unexpired, and screens that default to today still show the sample orders. You do not need to re-seed or set the date filter back to the original seed day. Quarterly stock-ledger samples stay in January, April, July, and September, and roll into the new year. On the first run it also fills 「送貨訂單」 so a search for today returns a row on each tab: 2/F and 4/F (pending, receiving, completed), Truck X, 加單, and 補貨. Those rows use `DEMO-` codes, so the same daily shift keeps their dates on today. The marker is setting `DEMO.do.showcase.v1`. In the log, expect: `Demo database login cannot read live schema fpsmsdb (MySQL error 1142).` Do not expect `Token updated`. That line means the process asked the live M18 server for a token. M18 screens are hidden. Calling them directly returns 403, for example `GET /api/m18/test/po-by-code`. ## 5. Start the frontend From `FPSMS-frontend`, on branch `debrand`: ```bash npm install npm run dev ``` Open `http://localhost:3000`. `.env.development` and `.env.production` on this branch both point at port 8090 on this machine. Do not point `NEXT_PUBLIC_API_URL` at `10.10.0.81` or any other live server. Sign in as `demo` / `Demo2026!`. ## If startup fails | Log | What to do | | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | Can read live schema `fpsmsdb` | The datasource user is too powerful. Recreate `fpsms_demo` as in step 3. Do not bypass the check. | | Access denied for `fpsms_demo` | The user or password does not match `application-db-demo.yml`, or the grants were not flushed. | | Liquibase tries to alter `fpsmsdb` | The changelog tables were not copied into `fpsms_demo`. Repeat step 2. With the restricted login this should fail closed, not change live data. | | Port 8090 already in use | Stop the other backend. Do not point the demo frontend at it. |