Skip to content

Releases: PPLEThai/pple-today

@api/backoffice@1.10.0

Choose a tag to compare

@github-actions github-actions released this 20 Jul 16:46
cb0420d

Minor Changes

  • #426 7b2634b Thanks @PanJ! - Expose today's notification send count for the platform Console Usage tile

    • New GET /platform/mini-apps/:id/notification-usage returns { sent } — how many audience-bound notifications the app's active key has sent in the current Asia/Bangkok quota day.
    • Uses the same NotificationApiKeyUsageLog window as the send path's claim, so the Console tile and a 429 cannot disagree on what "today" means.
    • Gated by the existing platform service token. An app with no active key returns NOTIFICATION_API_KEY_NOT_FOUND (unavailable on the platform side); zero sends today returns { sent: 0 }.

@pple-today/database@1.6.0

Choose a tag to compare

@github-actions github-actions released this 19 Jul 13:55
2c6986d

Minor Changes

  • #417 54f98b6 Thanks @PanJ! - Beta invites for Builder Apps

    • New MiniAppInvite model: a Builder invites a tester by phone number, and the invitation is delivered through the existing PPLE Today notification pipeline. The number is only a delivery address — accepting binds the invite to the invitee's account (userId), and listing eligibility matches on that alone, so changing a phone number never revokes access that was already consented to.
    • GET /mini-app/invites plus POST /mini-app/invites/:miniAppId/accept and /decline let the invitee see and answer their invitations. A Beta app appears in their mini app list only after they accept; pending and declined invitations show nothing.
    • The /platform service API gains GET/POST /platform/mini-apps/:id/invites and DELETE .../invites/:phoneNumber for managing an app's testers, behind the existing platform service token. The 20-tester cap is enforced here with an actionable error; removing a tester revokes their access and frees the seat, and a declined invitation does not hold one.
    • BETA-tier listing now resolves to the owner or an accepted invitee. DRAFT and LIVE visibility are unchanged.
    • Invited numbers are validated as Thai mobile numbers after normalisation, so a malformed number is rejected outright rather than stored as an undeliverable row holding one of the app's twenty tester seats.
    • notified reflects whether the invitation actually reached a PPLE Today account, not merely that the send call succeeded — the pipeline reports unmatched numbers as failed rather than erroring.
    • sendNotificationToUser now accepts sends with no notification API key, for platform-internal deliveries that have no key usage to meter. Existing keyed senders are unaffected.
  • #414 c9b2a51 Thanks @PanJ! - App User registration & per-app user count for Builder Apps

    • New MiniAppUser model ((miniAppId, userId) composite key, firstOpenedAt): the registry of who has opened each mini app. It is the consent boundary for audience-bound notifications and the source of the Console's per-app user count.
    • Opening a mini app now registers the caller as that app's App User on the token-exchange path (POST /auth/mini-app/:slug), for every tier. Registration is an idempotent upsert, so repeat opens are a no-op and preserve the original firstOpenedAt. It is best-effort: a registry write failure is logged, never surfaced, so it can't block a user from opening an app.
    • New service-to-service /platform API, gated by a dedicated PLATFORM_SERVICE_TOKEN (separate from admin/user auth; rejects all requests when unset). Its first endpoint, GET /platform/mini-apps/:id/user-count, returns the per-app App User count for the pple-platform provisioner.
  • #416 e2da97d Thanks @PanJ! - Platform service API for the Builder App lifecycle

    The /platform service-to-service API (gated by PLATFORM_SERVICE_TOKEN, separate from admin/user auth) gains the endpoints the pple-platform provisioner uses to drive a Builder App from creation to retirement. today-v2 remains the single writer of Zitadel state — every Zitadel effect flows through ZitadelService.

    • POST /platform/mini-apps — create a complete app registration in one call: a Zitadel OIDC app, a DRAFT/PLATFORM mini-app row owned by the Builder (ownerSub), and an app-bound notification key. Returns the clientId and the notification key (shown once, stored hashed). The app is immediately visible to its owner as a Draft.
    • PATCH /platform/mini-apps/:id — update name/icon/url; a URL change re-syncs the Zitadel redirect URIs before persisting.
    • PUT /platform/mini-apps/:id/tier — set the effective tier (DRAFT/BETA/LIVE).
    • PUT /platform/mini-apps/:id/roles — set the Live-tier visibility roles (reuses MiniAppRole; empty = everyone).
    • DELETE /platform/mini-apps/:id — retire the app: delete its Zitadel OIDC app, soft-delete the row (retiredAt), and deactivate its notification key. Retired apps are hidden from every mini-app list; the row and its App User registry are kept for audit.

    Every mutation invalidates the mini-app list cache so effects surface in PPLE Today promptly.

    Schema: MiniApp gains zitadelAppId (so retire can delete the OIDC app) and retiredAt (soft-retire); NotificationApiKey gains a nullable miniAppId binding it to an app (null = legacy central-team key, unchanged).

@pple-today/api-common@1.6.0

Choose a tag to compare

@github-actions github-actions released this 19 Jul 13:56
2c6986d

Minor Changes

  • #421 d4ca97d Thanks @PanJ! - Read-only admin view of platform-managed mini apps

    • The MiniApp DTO gains source (ADMIN/PLATFORM), ownerSub, and createdAt, exposed to the admin backoffice API alongside the existing fields.
    • The admin mini-app table shows tier, source, owner, and created date for every app, with a "จัดการโดย PPLE Platform" marker on platform-provisioned apps.
    • Platform-sourced apps have no edit/delete controls in the table and are rejected by the admin update/delete endpoints (MINI_APP_PLATFORM_MANAGED) — they're owned by the Provisioner, not this admin. Manual admin app management is unchanged for ADMIN-source apps.
  • #417 54f98b6 Thanks @PanJ! - Beta invites for Builder Apps

    • New MiniAppInvite model: a Builder invites a tester by phone number, and the invitation is delivered through the existing PPLE Today notification pipeline. The number is only a delivery address — accepting binds the invite to the invitee's account (userId), and listing eligibility matches on that alone, so changing a phone number never revokes access that was already consented to.
    • GET /mini-app/invites plus POST /mini-app/invites/:miniAppId/accept and /decline let the invitee see and answer their invitations. A Beta app appears in their mini app list only after they accept; pending and declined invitations show nothing.
    • The /platform service API gains GET/POST /platform/mini-apps/:id/invites and DELETE .../invites/:phoneNumber for managing an app's testers, behind the existing platform service token. The 20-tester cap is enforced here with an actionable error; removing a tester revokes their access and frees the seat, and a declined invitation does not hold one.
    • BETA-tier listing now resolves to the owner or an accepted invitee. DRAFT and LIVE visibility are unchanged.
    • Invited numbers are validated as Thai mobile numbers after normalisation, so a malformed number is rejected outright rather than stored as an undeliverable row holding one of the app's twenty tester seats.
    • notified reflects whether the invitation actually reached a PPLE Today account, not merely that the send call succeeded — the pipeline reports unmatched numbers as failed rather than erroring.
    • sendNotificationToUser now accepts sends with no notification API key, for platform-internal deliveries that have no key usage to meter. Existing keyed senders are unaffected.
  • #420 2d33915 Thanks @PanJ! - Full-phone identity lookup for Collaborators

    • POST /platform/users/lookup resolves a complete mobile number to { sub, name } behind the platform service token, so the Provisioner can ask an Owner to confirm a masked name before granting Collaborator access. Exact match only — incomplete or malformed numbers are reported as not-found and never searched as prefixes.
    • isThaiMobileE164 is extracted into @pple-today/api-common and shared with Beta invite phone validation, so "whole Thai mobile after normalisation" is one check rather than two copies of the same regex.

Patch Changes

  • #425 f8efa12 Thanks @PanJ! - Allow Builder Apps to self-deep-link notifications via optional linkPath on the audience-bound send route. Path-only values are joined to the sending app's redirect entry; absolute URLs and cross-app destinations are rejected with NOTIFICATION_INVALID_LINK_PATH.

  • Updated dependencies [54f98b6, c9b2a51, e2da97d]:

    • @pple-today/database@1.6.0

@client/backoffice@1.4.0

Choose a tag to compare

@github-actions github-actions released this 19 Jul 13:56
2c6986d

Minor Changes

  • #421 d4ca97d Thanks @PanJ! - Read-only admin view of platform-managed mini apps

    • The MiniApp DTO gains source (ADMIN/PLATFORM), ownerSub, and createdAt, exposed to the admin backoffice API alongside the existing fields.
    • The admin mini-app table shows tier, source, owner, and created date for every app, with a "จัดการโดย PPLE Platform" marker on platform-provisioned apps.
    • Platform-sourced apps have no edit/delete controls in the table and are rejected by the admin update/delete endpoints (MINI_APP_PLATFORM_MANAGED) — they're owned by the Provisioner, not this admin. Manual admin app management is unchanged for ADMIN-source apps.

@api/ballot-crypto@1.1.12

Choose a tag to compare

@github-actions github-actions released this 19 Jul 13:56
2c6986d

Patch Changes

@api/backoffice@1.9.0

Choose a tag to compare

@github-actions github-actions released this 19 Jul 13:55
2c6986d

Minor Changes

  • #421 d4ca97d Thanks @PanJ! - Read-only admin view of platform-managed mini apps

    • The MiniApp DTO gains source (ADMIN/PLATFORM), ownerSub, and createdAt, exposed to the admin backoffice API alongside the existing fields.
    • The admin mini-app table shows tier, source, owner, and created date for every app, with a "จัดการโดย PPLE Platform" marker on platform-provisioned apps.
    • Platform-sourced apps have no edit/delete controls in the table and are rejected by the admin update/delete endpoints (MINI_APP_PLATFORM_MANAGED) — they're owned by the Provisioner, not this admin. Manual admin app management is unchanged for ADMIN-source apps.
  • #417 54f98b6 Thanks @PanJ! - Beta invites for Builder Apps

    • New MiniAppInvite model: a Builder invites a tester by phone number, and the invitation is delivered through the existing PPLE Today notification pipeline. The number is only a delivery address — accepting binds the invite to the invitee's account (userId), and listing eligibility matches on that alone, so changing a phone number never revokes access that was already consented to.
    • GET /mini-app/invites plus POST /mini-app/invites/:miniAppId/accept and /decline let the invitee see and answer their invitations. A Beta app appears in their mini app list only after they accept; pending and declined invitations show nothing.
    • The /platform service API gains GET/POST /platform/mini-apps/:id/invites and DELETE .../invites/:phoneNumber for managing an app's testers, behind the existing platform service token. The 20-tester cap is enforced here with an actionable error; removing a tester revokes their access and frees the seat, and a declined invitation does not hold one.
    • BETA-tier listing now resolves to the owner or an accepted invitee. DRAFT and LIVE visibility are unchanged.
    • Invited numbers are validated as Thai mobile numbers after normalisation, so a malformed number is rejected outright rather than stored as an undeliverable row holding one of the app's twenty tester seats.
    • notified reflects whether the invitation actually reached a PPLE Today account, not merely that the send call succeeded — the pipeline reports unmatched numbers as failed rather than erroring.
    • sendNotificationToUser now accepts sends with no notification API key, for platform-internal deliveries that have no key usage to meter. Existing keyed senders are unaffected.
  • #414 c9b2a51 Thanks @PanJ! - App User registration & per-app user count for Builder Apps

    • New MiniAppUser model ((miniAppId, userId) composite key, firstOpenedAt): the registry of who has opened each mini app. It is the consent boundary for audience-bound notifications and the source of the Console's per-app user count.
    • Opening a mini app now registers the caller as that app's App User on the token-exchange path (POST /auth/mini-app/:slug), for every tier. Registration is an idempotent upsert, so repeat opens are a no-op and preserve the original firstOpenedAt. It is best-effort: a registry write failure is logged, never surfaced, so it can't block a user from opening an app.
    • New service-to-service /platform API, gated by a dedicated PLATFORM_SERVICE_TOKEN (separate from admin/user auth; rejects all requests when unset). Its first endpoint, GET /platform/mini-apps/:id/user-count, returns the per-app App User count for the pple-platform provisioner.
  • #416 e2da97d Thanks @PanJ! - Platform service API for the Builder App lifecycle

    The /platform service-to-service API (gated by PLATFORM_SERVICE_TOKEN, separate from admin/user auth) gains the endpoints the pple-platform provisioner uses to drive a Builder App from creation to retirement. today-v2 remains the single writer of Zitadel state — every Zitadel effect flows through ZitadelService.

    • POST /platform/mini-apps — create a complete app registration in one call: a Zitadel OIDC app, a DRAFT/PLATFORM mini-app row owned by the Builder (ownerSub), and an app-bound notification key. Returns the clientId and the notification key (shown once, stored hashed). The app is immediately visible to its owner as a Draft.
    • PATCH /platform/mini-apps/:id — update name/icon/url; a URL change re-syncs the Zitadel redirect URIs before persisting.
    • PUT /platform/mini-apps/:id/tier — set the effective tier (DRAFT/BETA/LIVE).
    • PUT /platform/mini-apps/:id/roles — set the Live-tier visibility roles (reuses MiniAppRole; empty = everyone).
    • DELETE /platform/mini-apps/:id — retire the app: delete its Zitadel OIDC app, soft-delete the row (retiredAt), and deactivate its notification key. Retired apps are hidden from every mini-app list; the row and its App User registry are kept for audit.

    Every mutation invalidates the mini-app list cache so effects surface in PPLE Today promptly.

    Schema: MiniApp gains zitadelAppId (so retire can delete the OIDC app) and retiredAt (soft-retire); NotificationApiKey gains a nullable miniAppId binding it to an app (null = legacy central-team key, unchanged).

  • #420 2d33915 Thanks @PanJ! - Full-phone identity lookup for Collaborators

    • POST /platform/users/lookup resolves a complete mobile number to { sub, name } behind the platform service token, so the Provisioner can ask an Owner to confirm a masked name before granting Collaborator access. Exact match only — incomplete or malformed numbers are reported as not-found and never searched as prefixes.
    • isThaiMobileE164 is extracted into @pple-today/api-common and shared with Beta invite phone validation, so "whole Thai mobile after normalisation" is one check rather than two copies of the same regex.

Patch Changes

  • #425 f8efa12 Thanks @PanJ! - Allow Builder Apps to self-deep-link notifications via optional linkPath on the audience-bound send route. Path-only values are joined to the sending app's redirect entry; absolute URLs and cross-app destinations are rejected with NOTIFICATION_INVALID_LINK_PATH.

  • #423 394226c Thanks @PanJ! - Make the Beta invite seat cap atomic under concurrency

    • Claiming a tester seat now runs in a single DB transaction that locks the app row before counting held invites and upserting, so two concurrent creates at seat 19 cannot both insert.
    • The 20-tester limit stays a service-level constant (MINI_APP_INVITE_LIMIT); over-cap still returns MINI_APP_INVITE_LIMIT_EXCEEDED naming the limit, and re-opening a declined invite still re-checks the cap.
  • #424 a89a50d Thanks @PanJ! - Make the notification daily quota atomic under concurrency

    • Claiming a send against a key's daily quota now runs in a single DB transaction that locks the NotificationApiKey row before counting usage and writing the log, so two concurrent sends at the last remaining slot cannot both insert.
    • The claim happens before the send; a failed send releases the claim so internal failures still do not consume budget. Empty-audience sends remain metered. 429 payload shape (dailyQuota, remaining, resetAt) is unchanged.
  • #422 c38503b Thanks @PanJ! - Tier-gate mini-app token exchange for Draft/Beta apps

    POST /auth/mini-app/:slug now applies the same eligibility rules as listing (isMiniAppVisible): Draft is owner-only, Beta is owner or ACCEPTED invitee, Live keeps the existing role filter (empty = public). Ineligible callers get MINI_APP_NOT_FOUND, so App User registration still runs only after a successful exchange.

  • Updated dependencies [f8efa12, d4ca97d, 54f98b6, c9b2a51, e2da97d, 2d33915]:

    • @pple-today/api-common@1.6.0
    • @pple-today/database@1.6.0

@pple-today/database@1.5.0

Choose a tag to compare

@github-actions github-actions released this 18 Jul 08:53
203407a

Minor Changes

  • #412 9172ee6 Thanks @PanJ! - Tier-aware mini app listing for Builder Apps

    • MiniApp gains tier (DRAFT/BETA/LIVE), source (ADMIN/PLATFORM), and ownerSub. Existing rows default to LIVE/ADMIN with no owner, so they stay visible under the current role rules exactly as before.
    • The mini app listing (GET /mini-app) is now tier-aware per requesting user: LIVE keeps its role-based visibility, while DRAFT and BETA apps are visible only to their owner (accepted BETA invitees come later). A Builder sees their own Draft in their normal list and nobody else does.
    • The listing response now includes tier so the client can badge non-LIVE apps.

@pple-today/api-common@1.5.0

Choose a tag to compare

@github-actions github-actions released this 18 Jul 08:53
203407a

Minor Changes

  • #412 9172ee6 Thanks @PanJ! - Tier-aware mini app listing for Builder Apps

    • MiniApp gains tier (DRAFT/BETA/LIVE), source (ADMIN/PLATFORM), and ownerSub. Existing rows default to LIVE/ADMIN with no owner, so they stay visible under the current role rules exactly as before.
    • The mini app listing (GET /mini-app) is now tier-aware per requesting user: LIVE keeps its role-based visibility, while DRAFT and BETA apps are visible only to their owner (accepted BETA invitees come later). A Builder sees their own Draft in their normal list and nobody else does.
    • The listing response now includes tier so the client can badge non-LIVE apps.

Patch Changes

  • Updated dependencies [9172ee6]:
    • @pple-today/database@1.5.0

@api/ballot-crypto@1.1.11

Choose a tag to compare

@github-actions github-actions released this 18 Jul 08:53
203407a

Patch Changes

  • Updated dependencies [9172ee6]:
    • @pple-today/api-common@1.5.0

@api/backoffice@1.8.0

Choose a tag to compare

@github-actions github-actions released this 18 Jul 08:53
203407a

Minor Changes

  • #412 9172ee6 Thanks @PanJ! - Tier-aware mini app listing for Builder Apps

    • MiniApp gains tier (DRAFT/BETA/LIVE), source (ADMIN/PLATFORM), and ownerSub. Existing rows default to LIVE/ADMIN with no owner, so they stay visible under the current role rules exactly as before.
    • The mini app listing (GET /mini-app) is now tier-aware per requesting user: LIVE keeps its role-based visibility, while DRAFT and BETA apps are visible only to their owner (accepted BETA invitees come later). A Builder sees their own Draft in their normal list and nobody else does.
    • The listing response now includes tier so the client can badge non-LIVE apps.

Patch Changes

  • Updated dependencies [9172ee6]:
    • @pple-today/api-common@1.5.0
    • @pple-today/database@1.5.0