Lab Case Detail datatset load faliure fixed.
All checks were successful
Production — tag build, push, deploy / build-and-push (push) Successful in 26m42s
Production — tag build, push, deploy / deploy (push) Successful in 13m27s

This commit is contained in:
2026-09-07 20:41:18 +03:30
parent 0d2c279f4b
commit b1bcfc69e4
9 changed files with 20 additions and 9 deletions

View File

@@ -17,10 +17,13 @@ Ops panel at `/admin` (`backend/src/admin/`). Resources are a **manual allowlist
3. **Renamed / removed model** → update or remove the matching resource (broken `getModelByName` breaks `/admin` boot).
4. **New secret fields** (hashes, tokens, share tokens) → hide via `isVisible: false` (list/filter/show/edit).
5. **Catalog-like reference data** → list/show/edit only; disable `new` / `delete` / `bulkDelete`.
6. Skip pure join/cursor tables unless ops need them (`LabCaseUserReadState`, `LabCaseUserTabReadState`, working-hours, `LabCaseAttachment`).
6. **Composite `@@id` only** (no single `@id`) → **do not register** — AdminJS list returns 500 (`Resource does not have an id property`). Examples: `LabCaseDetail`, `MembershipPermission`, read-cursor tables.
7. Skip pure join/cursor tables unless ops need them and they have a single id.
Auth: `ADMINJS_EMAIL` / `ADMINJS_PASSWORD` — production login disabled if password missing or still `admin123`.
Production Docker: `ADMIN_JS_TMP_DIR=/app/adminjs-tmp` (not `.adminjs`) so `components.bundle.js` can be written/served.
## Secrets to hide
`passwordHash`, session `token`/`refreshToken`, invite/OTP `tokenHash`/`codeHash`, `LabCase.accessToken`.

View File

@@ -92,7 +92,7 @@ backend/src/
Errors: `AppException` + `ErrorCode` → frontend `getUserFacingError()`. Unexpected 500s: GlitchTip (`SENTRY_DSN`). Never throw raw strings for user-facing failures.
**AdminJS:** Manual resource allowlist in `backend/src/admin/resources.ts`. **Whenever `schema.prisma` changes**, update AdminJS resources in the same task (new/renamed/removed models, hide secrets). Rule: `.cursor/rules/adminjs.mdc`.
**AdminJS:** Manual resource allowlist in `backend/src/admin/resources.ts`. **Whenever `schema.prisma` changes**, update AdminJS resources in the same task (new/renamed/removed models, hide secrets). Models with only composite `@@id` must not be registered (list 500). Rule: `.cursor/rules/adminjs.mdc`.
## Git & commits

View File

@@ -53,7 +53,11 @@ COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
# Windows git/build context may use CRLF; strip before chmod (fixes dumb-init "No such file or directory").
RUN sed -i 's/\r$//' /usr/local/bin/docker-entrypoint.sh && chmod +x /usr/local/bin/docker-entrypoint.sh
RUN mkdir -p /app/logs && \
# AdminJS writes/serves the custom-components bundle here. Avoid the default
# ".adminjs" path — Express sendFile + nosniff can 500 on dot-directories.
ENV ADMIN_JS_TMP_DIR=/app/adminjs-tmp
RUN mkdir -p /app/logs /app/adminjs-tmp && \
chown -R dyolink:nodejs /app
USER dyolink

View File

@@ -76,9 +76,7 @@ export function buildAdminResources(prisma: PrismaService): AdminResource[] {
resource(prisma, 'Permission', {
navigation: { name: 'Orgs & access', icon: 'Settings' },
}),
resource(prisma, 'MembershipPermission', {
navigation: { name: 'Orgs & access', icon: 'Settings' },
}),
// MembershipPermission omitted: composite @@id — AdminJS list 500s without a single id
resource(prisma, 'Feature', {
navigation: { name: 'Orgs & access', icon: 'Settings' },
}),
@@ -119,9 +117,8 @@ export function buildAdminResources(prisma: PrismaService): AdminResource[] {
resource(prisma, 'LabCaseLine', {
navigation: { name: 'Lab', icon: 'Archive' },
}),
resource(prisma, 'LabCaseDetail', {
navigation: { name: 'Lab', icon: 'Archive' },
}),
// LabCaseDetail omitted: composite @@id — AdminJS list 500s without a single id
// (inspect LabCase + TreatmentDetail instead)
resource(prisma, 'LabCaseSend', {
navigation: { name: 'Lab', icon: 'Archive' },
}),

View File

@@ -18,6 +18,8 @@ FRONTEND_URL=https://nudentic.ir
# Change these — the code defaults are only for local development.
ADMINJS_EMAIL=admin@nudentic.ir
ADMINJS_PASSWORD=CHANGE_ME_STRONG_ADMINJS_PASSWORD
# Optional override; Docker image sets /app/adminjs-tmp (do not use ".adminjs").
# ADMIN_JS_TMP_DIR=/app/adminjs-tmp
# Required for HTTPS — browsers reject Secure cookies over plain HTTP
COOKIE_SECURE=true

View File

@@ -15,6 +15,8 @@ FRONTEND_URL=https://wixur.ir
# AdminJS at https://wixur.ir/admin (nginx proxies /admin to the API).
ADMINJS_EMAIL=admin@wixur.ir
ADMINJS_PASSWORD=CHANGE_ME_STRONG_ADMINJS_PASSWORD
# Optional override; Docker image sets /app/adminjs-tmp (do not use ".adminjs").
# ADMIN_JS_TMP_DIR=/app/adminjs-tmp
# TLS is terminated on Windows nginx :443 — cookies must be Secure
COOKIE_SECURE=true

View File

@@ -48,6 +48,7 @@ services:
NODE_ENV: production
TZ: UTC
PORT: "3000"
ADMIN_JS_TMP_DIR: /app/adminjs-tmp
SENTRY_ENVIRONMENT: production
SENTRY_RELEASE: ${TAG:-latest}
expose:

View File

@@ -47,6 +47,7 @@ services:
NODE_ENV: production
TZ: UTC
PORT: "3000"
ADMIN_JS_TMP_DIR: /app/adminjs-tmp
SENTRY_ENVIRONMENT: staging
SENTRY_RELEASE: ${IMAGE_TAG:-latest}
expose:

View File

@@ -43,6 +43,7 @@ services:
NODE_ENV: production
TZ: UTC
PORT: "3000"
ADMIN_JS_TMP_DIR: /app/adminjs-tmp
SENTRY_ENVIRONMENT: staging
expose:
- "3000"