Skip to content

Feature/complete dashboard sync - #3750

Closed
master-kanor wants to merge 41 commits into
tdlib:masterfrom
hillstreet-ph:feature/complete-dashboard-sync
Closed

master-kanor wants to merge 41 commits into
tdlib:masterfrom
hillstreet-ph:feature/complete-dashboard-sync

Conversation

@master-kanor

Copy link
Copy Markdown

No description provided.

master-kanor and others added 30 commits August 22, 2026 13:06
Bumps the npm_and_yarn group with 7 updates in the /example/web/tdweb directory:

| Package | From | To |
| --- | --- | --- |
| [@babel/runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime) | `7.4.3` | `7.29.7` |
| [uuid](https://github.com/uuidjs/uuid) | `3.3.2` | `14.0.0` |
| [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) | `7.4.3` | `7.29.6` |
| [brace-expansion](https://github.com/juliangruber/brace-expansion) | `1.1.11` | `1.1.18` |
| [braces](https://github.com/micromatch/braces) | `2.3.2` | `removed` |
| [flatted](https://github.com/WebReflection/flatted) | `2.0.0` | `3.4.4` |
| [lodash](https://github.com/lodash/lodash) | `4.17.21` | `4.18.1` |



Updates `@babel/runtime` from 7.4.3 to 7.29.7
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.29.7/packages/babel-runtime)

Updates `uuid` from 3.3.2 to 14.0.0
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](uuidjs/uuid@v3.3.2...v14.0.0)

Updates `@babel/core` from 7.4.3 to 7.29.6
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.29.6/packages/babel-core)

Updates `brace-expansion` from 1.1.11 to 1.1.18
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](juliangruber/brace-expansion@1.1.11...v1.1.18)

Removes `braces`

Updates `flatted` from 2.0.0 to 3.4.4
- [Commits](WebReflection/flatted@v2.0.0...v3.4.4)

Updates `js-yaml` from 3.13.1 to 3.15.1
- [Changelog](https://github.com/nodeca/js-yaml/blob/3.15.1/CHANGELOG.md)
- [Commits](nodeca/js-yaml@3.13.1...3.15.1)

Updates `lodash` from 4.17.21 to 4.18.1
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](lodash/lodash@4.17.21...4.18.1)

Updates `picomatch` from 2.2.2 to 4.0.5
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](micromatch/picomatch@2.2.2...4.0.5)

---
updated-dependencies:
- dependency-name: "@babel/runtime"
  dependency-version: 7.29.7
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: uuid
  dependency-version: 14.0.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: "@babel/core"
  dependency-version: 7.29.6
  dependency-type: direct:development
  dependency-group: npm_and_yarn
- dependency-name: brace-expansion
  dependency-version: 1.1.18
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: braces
  dependency-version:
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: flatted
  dependency-version: 3.4.4
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: js-yaml
  dependency-version: 3.15.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.18.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: picomatch
  dependency-version: 4.0.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Bootstrap Open-TGate private operations architecture
…ple/web/tdweb/npm_and_yarn-b80a115b7c

Bump the npm_and_yarn group across 1 directory with 9 updates
Configure professional branching and Actions secret contract
* feat: implement Open-TGate production vertical slice

* ci: set application import path for tests
* fix: make Dockerfile.api Railway-compatible

* fix: make Dockerfile.worker Railway-compatible

* ci: build API image from repository context
Sync latest upstream TDLib changes into development
Promote validated Open-TGate release to production
* test: cover malformed variables and placeholders

* fix: harden runtime environment parsing

* fix: initialize Railway volume before dropping privileges

* fix: add worker volume initialization entrypoint
Promote Railway runtime hardening to production
Validated PR #16: mergeable, scoped diff reviewed, and required CI successful.
Validated PR #15: mergeable, scoped diff reviewed, and required CI successful.
Bumps the npm_and_yarn group with 1 update in the /example/web/tdweb directory: [minimatch](https://github.com/isaacs/minimatch).


Updates `minimatch` from 3.1.2 to 3.1.5
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](isaacs/minimatch@v3.1.2...v3.1.5)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* docs: define autonomous delivery and release contract

* ci: add automated semantic releases

* ci: configure release please

* ci: bootstrap release version tracking

* ci: publish semantic Docker Hub releases
* fix(runtime): provide worker TDLib path defaults

* test(ci): gate Railway API and worker runtime startup
Capture complete logs before matching startup and require the worker to remain running.

Signed-off-by: Charles Tanauan <297973909+master-kanor@users.noreply.github.com>
…d applied DB runtime (#24)

* feat(backend): make Telegram backend Zeabur-deployable with Sentry and DB runtime

Advance the Open-TGate backend along the canonical stack (GitHub → Docker Hub →
Zeabur → Supabase → Sentry) and fix release/runtime gaps found during inspection.

Supabase
- Rework the runtime migration to be additive and isolated on the shared
  open-operations project: a reserved open_tgate schema and a service-only
  public.open_tgate_worker_heartbeats table (RLS on, no anon/authenticated).
- Point the worker heartbeat at the prefixed table (PostgREST-reachable without
  changing the shared gateway's exposed schemas).

Sentry
- Add DSN-gated Sentry init in a shared observability module, wired into the API
  and worker. No-op when SENTRY_DSN is unset; never crashes the service.
- Add sentry-sdk[fastapi] and SENTRY_* to the env contract; add tests proving the
  disabled/placeholder/enabled paths.

Docker Hub
- Fix release-dockerhub.yml, which built a non-existent root Dockerfile. Publish
  both open-tgate-api (amd64+arm64) and open-tgate-worker (amd64; native TDLib)
  with semver/sha tags, provenance and SBOM.

Zeabur
- Add deploy/zeabur (template scaffold + authoritative deploy guide): api web
  service with /healthz health check, worker service with a persistent
  /data/tdlib volume; repoint the dashboard off the legacy Railway URL.

Docs
- Update env/secret contract and platform docs for Sentry + Zeabur, mark Railway
  legacy, and record that Databricks is out of the canonical stack pending
  approval and a stated technical requirement.

EXTERNAL_SEND_ENABLED stays false. Validated: ruff clean, 8/8 pytest, YAML parses,
migration applied and verified on open-operations.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EGqfXSDRSWXVmnDhGyuaw1

* ci(security): pin docker/setup-qemu-action to an immutable SHA

CodeQL flagged the newly added setup-qemu-action step as an unpinned
third-party action. Pin it to the commit the v3 tag currently resolves to
(c7c5346 = v3.7.0) so the release build cannot be silently changed upstream.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EGqfXSDRSWXVmnDhGyuaw1

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
master-kanor and others added 11 commits September 22, 2026 05:59
…n plan (#25)

Replace the bare Cloudflare Worker status page with a full, responsive
landing page (dark/light, accessible, strict CSP) that presents the
architecture, capabilities, delivery stack, and safety posture, while
preserving the edge contract: only /healthz is proxied to the Zeabur API
and all /api/ paths are refused.

- dashboard/src/site.js: self-contained landing page (inline CSS + tiny
  theme/status script; no third-party resources)
- dashboard/src/index.js: serve the page, harden CSP and security headers,
  keep /healthz proxy and /api/ block; graceful upstream error handling
- gitignore dashboard node_modules and .wrangler
- roadmap/PRODUCTIZATION_PLAN.md: phased design for TDLib multi-account
  read-only sync (contacts/groups/channels/bots/files), realtime + outbox,
  ban-avoidance guardrails, downstream AI knowledge base, and the
  credential/BLOCKED list for going live on Zeabur

Validated with `wrangler deploy --dry-run` (bundles clean) and rendered
in headless Chromium (dark + light).


Claude-Session: https://claude.ai/code/session_01DXdLQH1je2J5oSC1qWjhKc

Co-authored-by: Claude <noreply@anthropic.com>
* ci(deploy): add Cloudflare Worker deploy workflow + verified deploy map

Add .github/workflows/deploy-dashboard.yml to publish the dashboard Worker
from a GitHub runner (open egress), gated on CLOUDFLARE_API_TOKEN and
CLOUDFLARE_ACCOUNT_ID repository secrets. It is a no-op (green) until those
secrets exist, then deploys on push to master or manual dispatch.

Add open-tgate/roadmap/DEPLOY_STATUS.md recording the verified Supabase
project for open-tgate (open-operations / hoseohvgoiarxluxqwqv, not
open-platform), the session egress constraint, and the secret→platform→
destination map (names only, no secret values).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DXdLQH1je2J5oSC1qWjhKc

* ci(deploy): address review — no false-green, pin actions to SHA

Rework deploy-dashboard.yml per maintenance review on #28:

- Split into two jobs so a green run never implies a deploy that did not
  happen: `validate` always builds/bundles the Worker (wrangler --dry-run,
  no credentials); `deploy` runs only when repo variable
  DASHBOARD_DEPLOY_ENABLED == 'true' (explicit provider-config confirmation)
  and FAILS LOUDLY if the required Cloudflare secrets are then missing.
  Removes the previous silent no-op success path.
- Pin actions/checkout to commit SHA 11d5960 (# v4), matching the pins being
  standardized in the Docker release workflow. Drop actions/setup-node and
  use the runner's preinstalled Node, reducing third-party action surface.
- Document the DASHBOARD_DEPLOY_ENABLED opt-in in DEPLOY_STATUS.md.

Validated: YAML parses; wrangler --dry-run bundles clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DXdLQH1je2J5oSC1qWjhKc

---------

Co-authored-by: Claude <noreply@anthropic.com>
)

* docs(deploy): keep DEPLOY_STATUS to durable config + operator steps

Follow-up to review on #28 (merged):
- Remove the unrelated excluded-project tenant identifier; the guide now
  names only open-tgate's own Supabase project (open-operations).
- Remove the transient agent-session egress narrative; it is session-
  specific and would go stale. Keep only durable provider configuration
  and operator deploy steps.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DXdLQH1je2J5oSC1qWjhKc

* feat(dashboard): operator login console (/app) via Supabase Auth

Add a real login-gated operator console to the Cloudflare Worker dashboard.

Frontend (dashboard/src/app.js, routed in index.js):
- /app serves a Supabase Auth email magic-link login and, once signed in,
  an operator console showing live worker heartbeats.
- Access is gated by the open_tgate_operators allowlist + RLS: a signed-in
  non-operator sees a "not authorized" screen and can read no data.
- Worker status is read directly from Supabase (PostgREST, RLS-restricted),
  so the console works without the API deployed.
- Dedicated CSP for /app (allows the Supabase JS SDK from jsDelivr and
  fetch/XHR to the Supabase origin); the landing page keeps its strict CSP.
- Public landing page gains an "Operator login" link.

Config (wrangler.toml [vars]): SUPABASE_URL + SUPABASE_PUBLISHABLE_KEY
(both public by design). The service/secret key is never placed here.

Backend (Supabase, applied via migrations on open-operations):
- public.open_tgate_operators (email allowlist) with RLS self-select.
- public.open_tgate_is_operator() (SECURITY INVOKER) helper.
- SELECT policy letting active operators read open_tgate_worker_heartbeats.
- Initial admin operator seeded.

Validated: wrangler --dry-run bundles clean (4 vars bound); login view
renders; Supabase security advisors clean for the new objects.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DXdLQH1je2J5oSC1qWjhKc

---------

Co-authored-by: Claude <noreply@anthropic.com>
* feat(dashboard): add password, Google and GitHub sign-in to /app

* fix(dashboard): replace self-signup with email-verified password reset

Addresses Codex review on #30:
- P1 (security): the client-side signUp path could create an authenticated
  session for any allowlisted email without proving control of that address,
  letting a stranger claim an allowlisted operator email. Remove signUp
  entirely.
- P2: signUp could not set a password for an operator who already exists
  (e.g. from a magic-link login).

New "Set / reset password" flow uses resetPasswordForEmail -> PASSWORD_RECOVERY
session -> updateUser({password}). A password can only be set by whoever
controls the operator's inbox, and it works for existing users. Password
sign-in (signInWithPassword), magic link, and Google/GitHub OAuth unchanged.

Validated: wrangler --dry-run bundles clean; no signUp remains.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DXdLQH1je2J5oSC1qWjhKc

* deploy(zeabur): pin template to hillstreet/open-tgate-{api,worker}:1.0.0 + SUPABASE_URL

Make the Docker Hub -> Zeabur import turnkey: reference the actual published
images (namespace hillstreet, immutable v1.0.0 tag) instead of the
DOCKERHUB_USERNAME/...:latest placeholder, and pre-fill the non-secret
SUPABASE_URL on both services. Secrets still set in the Zeabur secret store.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DXdLQH1je2J5oSC1qWjhKc

* fix(dashboard): harden password-recovery flow (Codex P1/P2)

- P1 (race): a password-recovery load could be overwritten by the async
  initial getSession->renderFor before the recovery guard was set. Detect
  type=recovery from the URL synchronously and lock to the set-password
  view up front; skip the initial render while recovering; renderFor now
  bails to the recovery view if recovering.
- P2 (onboarding): first-time operators with no Auth user can't use
  resetPasswordForEmail. Sign-in and reset messages now direct first-time
  users to magic link or Google/GitHub (which provision the account) before
  setting a password.

Validated: wrangler --dry-run bundles clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DXdLQH1je2J5oSC1qWjhKc

---------

Co-authored-by: Claude <noreply@anthropic.com>
Add the Open-TGate-specific AI worker protocol and canonical HillStreet references after all checks passed.
…d-only auto-sync (#31)

* feat(dashboard): add password, Google and GitHub sign-in to /app

* fix(dashboard): replace self-signup with email-verified password reset

Addresses Codex review on #30:
- P1 (security): the client-side signUp path could create an authenticated
  session for any allowlisted email without proving control of that address,
  letting a stranger claim an allowlisted operator email. Remove signUp
  entirely.
- P2: signUp could not set a password for an operator who already exists
  (e.g. from a magic-link login).

New "Set / reset password" flow uses resetPasswordForEmail -> PASSWORD_RECOVERY
session -> updateUser({password}). A password can only be set by whoever
controls the operator's inbox, and it works for existing users. Password
sign-in (signInWithPassword), magic link, and Google/GitHub OAuth unchanged.

Validated: wrangler --dry-run bundles clean; no signUp remains.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DXdLQH1je2J5oSC1qWjhKc

* deploy(zeabur): pin template to hillstreet/open-tgate-{api,worker}:1.0.0 + SUPABASE_URL

Make the Docker Hub -> Zeabur import turnkey: reference the actual published
images (namespace hillstreet, immutable v1.0.0 tag) instead of the
DOCKERHUB_USERNAME/...:latest placeholder, and pre-fill the non-secret
SUPABASE_URL on both services. Secrets still set in the Zeabur secret store.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DXdLQH1je2J5oSC1qWjhKc

* fix(dashboard): harden password-recovery flow (Codex P1/P2)

- P1 (race): a password-recovery load could be overwritten by the async
  initial getSession->renderFor before the recovery guard was set. Detect
  type=recovery from the URL synchronously and lock to the set-password
  view up front; skip the initial render while recovering; renderFor now
  bails to the recovery view if recovering.
- P2 (onboarding): first-time operators with no Auth user can't use
  resetPasswordForEmail. Sign-in and reset messages now direct first-time
  users to magic link or Google/GitHub (which provision the account) before
  setting a password.

Validated: wrangler --dry-run bundles clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DXdLQH1je2J5oSC1qWjhKc

* feat(telegram): in-platform multi-account login (phone + QR) with read-only auto-sync

Add end-to-end Telegram account login inside the /app operator console:
connect multiple accounts by phone number or QR code, then mirror each
account's contacts/groups/channels/bots/files read-only, like the official
app populates after sign-in.

Backend (worker + API):
- app/telegram/authflow.py: pure TDLib authorization state machine for phone
  and QR login (setTdlibParameters → phone/QR → code → optional 2FA → ready);
  refuses account registration and email login; FLOOD_WAIT parsing.
- app/telegram/sync.py: pure normalisation of chats/users/files into entity
  rows; chat classification; phone masking; no AI/Notion dependency.
- app/telegram/tdjson.py: thin ctypes bridge to libtdjson (lazy-loaded).
- app/telegram/manager.py: multi-account runtime — single receive pump routed
  by @client_id, ban-safe pacing, honours FLOOD_WAIT, read-only sync.
- app/telegram/bus.py: Supabase command/event bus + command validation +
  Decision→account-row mapping.
- app/api_accounts.py: admin-gated /api/v1/telegram/{accounts,commands}.
- worker runs the account manager alongside heartbeats only when Telegram +
  Supabase credentials are configured (dormant otherwise, so CI stays green).

Database:
- supabase migration open_tgate_telegram_accounts: accounts / login_commands /
  entities with operator RLS (operators INSERT-only on commands so one-time
  codes/2FA passwords cannot be read back); service-role writes results.

Frontend:
- /app operator console: "Connect account" flow, phone/QR login, inline
  code/password entry, QR rendering, live status + synced-entity counts,
  3s polling that preserves in-progress input.

Security/safety:
- TDLib session material stays only on the worker volume; login secrets ride a
  command row transiently and are nulled on consume; phones stored masked.
- Sync is read-only; EXTERNAL_SEND_ENABLED stays false.

Tests: 32 unit tests (login handshake, QR, sync, command contract, API gate);
ruff clean; dashboard Worker bundles; migration applied + advisor clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DXdLQH1je2J5oSC1qWjhKc

---------

Co-authored-by: Claude <noreply@anthropic.com>
@shariatianhh-droid

shariatianhh-droid commented Sep 24, 2026 via email

Copy link
Copy Markdown

@levlam

levlam commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

This is out-of-scope for this repository.

@levlam levlam closed this Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants