Raw JSON report machine-readable
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 62353,
"has_wiki": true,
"homepage": "https://ppanel.dev",
"languages": {
"Go": 2900530,
"Lua": 1305,
"HTML": 29952,
"Shell": 3515,
"PLpgSQL": 185759,
"Makefile": 2284,
"Dockerfile": 1308,
"TypeScript": 4059
},
"pushed_at": "2026-07-24T13:43:19Z",
"created_at": "2025-04-25T03:01:36Z",
"owner_type": "Organization",
"updated_at": "2026-07-24T13:44:50Z",
"description": "PPanel is a pure, professional, and perfect open-source proxy panel tool, designed to be your ideal choice for learning and practical use.",
"is_archived": false,
"is_disabled": false,
"license_spdx": "GPL-3.0",
"default_branch": "master",
"license_spdx_raw": "GPL-3.0",
"primary_language": "Go",
"significant_languages": [
"Go"
]
},
"owner": {
"blog": "ppanel.dev",
"name": "PPanel",
"type": "Organization",
"login": "perfect-panel",
"company": null,
"location": null,
"followers": 203,
"avatar_url": "https://avatars.githubusercontent.com/u/181395280?v=4",
"created_at": "2024-09-12T16:54:42Z",
"is_verified": null,
"public_repos": 21,
"account_age_days": 679
},
"license": {
"state": "standard",
"spdx_id": "GPL-3.0",
"raw_spdx": "GPL-3.0",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v1.15.0",
"kind": "minor",
"published_at": "2026-07-24T13:17:58Z"
},
{
"tag": "v1.14.22",
"kind": "patch",
"published_at": "2026-07-24T04:46:11Z"
},
{
"tag": "v1.14.21",
"kind": "patch",
"published_at": "2026-07-24T04:27:41Z"
},
{
"tag": "v1.14.20",
"kind": "patch",
"published_at": "2026-07-23T14:42:20Z"
},
{
"tag": "v1.14.19",
"kind": "patch",
"published_at": "2026-07-23T14:11:37Z"
},
{
"tag": "v1.14.18",
"kind": "patch",
"published_at": "2026-07-23T08:11:24Z"
},
{
"tag": "v1.14.17",
"kind": "patch",
"published_at": "2026-07-23T06:43:18Z"
},
{
"tag": "v1.14.16",
"kind": "patch",
"published_at": "2026-07-22T18:51:40Z"
},
{
"tag": "v1.14.15",
"kind": "patch",
"published_at": "2026-07-22T18:07:42Z"
},
{
"tag": "v1.14.14",
"kind": "patch",
"published_at": "2026-07-22T09:26:47Z"
},
{
"tag": "v1.14.13",
"kind": "patch",
"published_at": "2026-07-22T09:12:44Z"
},
{
"tag": "v1.14.12",
"kind": "patch",
"published_at": "2026-07-22T08:25:37Z"
},
{
"tag": "v1.14.11",
"kind": "patch",
"published_at": "2026-07-22T06:33:40Z"
},
{
"tag": "v1.14.10",
"kind": "patch",
"published_at": "2026-07-22T05:38:49Z"
},
{
"tag": "v1.14.9",
"kind": "patch",
"published_at": "2026-07-22T05:34:37Z"
},
{
"tag": "v1.14.8",
"kind": "patch",
"published_at": "2026-07-22T01:40:03Z"
},
{
"tag": "v1.14.7",
"kind": "patch",
"published_at": "2026-07-20T21:51:40Z"
},
{
"tag": "v1.14.6",
"kind": "patch",
"published_at": "2026-07-20T12:02:42Z"
},
{
"tag": "v1.14.5",
"kind": "patch",
"published_at": "2026-07-20T11:16:49Z"
},
{
"tag": "v1.14.4",
"kind": "patch",
"published_at": "2026-07-20T07:37:02Z"
},
{
"tag": "v1.14.3",
"kind": "patch",
"published_at": "2026-07-20T05:59:11Z"
},
{
"tag": "v1.14.2",
"kind": "patch",
"published_at": "2026-07-17T03:08:07Z"
},
{
"tag": "v1.14.1",
"kind": "patch",
"published_at": "2026-07-16T17:08:45Z"
},
{
"tag": "v1.14.0",
"kind": "minor",
"published_at": "2026-07-16T03:45:44Z"
},
{
"tag": "v1.3.16",
"kind": "patch",
"published_at": "2026-07-15T19:21:25Z"
},
{
"tag": "v1.3.15",
"kind": "patch",
"published_at": "2026-07-14T13:43:30Z"
},
{
"tag": "v1.3.14",
"kind": "patch",
"published_at": "2026-07-14T10:43:13Z"
},
{
"tag": "v1.3.13",
"kind": "patch",
"published_at": "2026-07-13T15:54:14Z"
},
{
"tag": "v1.3.12",
"kind": "patch",
"published_at": "2026-07-10T10:32:55Z"
},
{
"tag": "v1.3.11",
"kind": "patch",
"published_at": "2026-07-07T12:41:07Z"
},
{
"tag": "v1.3.10",
"kind": "patch",
"published_at": "2026-07-07T11:14:13Z"
},
{
"tag": "v1.3.9",
"kind": "patch",
"published_at": "2026-07-07T10:01:23Z"
},
{
"tag": "v1.3.8",
"kind": "patch",
"published_at": "2026-06-28T17:26:03Z"
},
{
"tag": "v1.3.7",
"kind": "patch",
"published_at": "2026-06-28T15:21:07Z"
},
{
"tag": "v1.3.6",
"kind": "patch",
"published_at": "2026-06-28T09:14:56Z"
},
{
"tag": "v1.3.5",
"kind": "patch",
"published_at": "2026-06-28T09:10:13Z"
},
{
"tag": "v1.3.4",
"kind": "patch",
"published_at": "2026-06-28T09:01:53Z"
},
{
"tag": "v1.3.3",
"kind": "patch",
"published_at": "2026-06-21T14:15:56Z"
},
{
"tag": "v1.3.2",
"kind": "patch",
"published_at": "2026-06-21T14:10:45Z"
},
{
"tag": "v1.3.1",
"kind": "patch",
"published_at": "2026-06-20T13:37:26Z"
},
{
"tag": "v1.3.0",
"kind": "minor",
"published_at": "2026-06-20T11:50:34Z"
},
{
"tag": "v1.2.31",
"kind": "patch",
"published_at": "2026-06-18T20:59:04Z"
},
{
"tag": "v1.2.30",
"kind": "patch",
"published_at": "2026-06-18T10:30:55Z"
},
{
"tag": "v1.2.29",
"kind": "patch",
"published_at": "2026-06-12T03:01:01Z"
},
{
"tag": "v1.2.28",
"kind": "patch",
"published_at": "2026-06-11T01:21:02Z"
},
{
"tag": "v1.2.27",
"kind": "patch",
"published_at": "2026-06-10T10:34:38Z"
},
{
"tag": "v1.2.26",
"kind": "patch",
"published_at": "2026-06-10T06:47:52Z"
},
{
"tag": "v1.2.24",
"kind": "patch",
"published_at": "2026-06-09T09:33:51Z"
},
{
"tag": "v1.2.23",
"kind": "patch",
"published_at": "2026-06-09T09:24:08Z"
},
{
"tag": "v1.2.22",
"kind": "patch",
"published_at": "2026-06-09T07:46:47Z"
},
{
"tag": "v1.2.21",
"kind": "patch",
"published_at": "2026-06-09T00:15:59Z"
},
{
"tag": "v1.2.20",
"kind": "patch",
"published_at": "2026-06-08T22:45:21Z"
},
{
"tag": "v1.2.19",
"kind": "patch",
"published_at": "2026-06-08T17:04:40Z"
},
{
"tag": "v1.2.18",
"kind": "patch",
"published_at": "2026-06-05T16:25:20Z"
},
{
"tag": "v1.2.17",
"kind": "patch",
"published_at": "2026-06-04T17:43:08Z"
},
{
"tag": "v1.2.16",
"kind": "patch",
"published_at": "2026-06-04T12:01:19Z"
},
{
"tag": "v1.2.15",
"kind": "patch",
"published_at": "2026-05-23T04:43:51Z"
},
{
"tag": "v1.2.14",
"kind": "patch",
"published_at": "2026-05-20T12:48:42Z"
},
{
"tag": "v1.2.13",
"kind": "patch",
"published_at": "2026-05-19T07:54:09Z"
},
{
"tag": "v1.2.12",
"kind": "patch",
"published_at": "2026-05-18T08:36:48Z"
},
{
"tag": "v1.2.11",
"kind": "patch",
"published_at": "2026-05-10T07:06:37Z"
},
{
"tag": "v1.2.10",
"kind": "patch",
"published_at": "2026-05-10T06:52:03Z"
},
{
"tag": "v1.2.9",
"kind": "patch",
"published_at": "2026-05-10T06:39:12Z"
},
{
"tag": "v1.2.8",
"kind": "patch",
"published_at": "2026-02-08T12:09:09Z"
},
{
"tag": "v1.2.7",
"kind": "patch",
"published_at": "2026-01-07T14:58:02Z"
},
{
"tag": "v1.2.6",
"kind": "patch",
"published_at": "2026-01-03T10:25:05Z"
},
{
"tag": "v1.2.5",
"kind": "patch",
"published_at": "2025-12-31T09:42:33Z"
},
{
"tag": "v1.2.4",
"kind": "patch",
"published_at": "2025-12-30T08:42:26Z"
},
{
"tag": "v1.2.3",
"kind": "patch",
"published_at": "2025-12-29T07:32:51Z"
},
{
"tag": "v1.2.2",
"kind": "patch",
"published_at": "2025-12-08T08:29:43Z"
},
{
"tag": "v1.2.1",
"kind": "patch",
"published_at": "2025-12-08T08:10:24Z"
},
{
"tag": "v1.2.0",
"kind": "minor",
"published_at": "2025-12-03T15:29:00Z"
},
{
"tag": "v1.1.10",
"kind": "patch",
"published_at": "2025-10-22T14:59:28Z"
},
{
"tag": "v1.1.9",
"kind": "patch",
"published_at": "2025-10-20T14:42:04Z"
},
{
"tag": "v1.1.8",
"kind": "patch",
"published_at": "2025-10-18T09:03:11Z"
},
{
"tag": "v1.1.7",
"kind": "patch",
"published_at": "2025-10-04T16:21:12Z"
},
{
"tag": "v1.1.6",
"kind": "patch",
"published_at": "2025-10-03T19:42:32Z"
},
{
"tag": "v1.1.5",
"kind": "patch",
"published_at": "2025-10-02T09:43:03Z"
},
{
"tag": "v1.1.4",
"kind": "patch",
"published_at": "2025-09-29T15:57:17Z"
},
{
"tag": "v1.1.3",
"kind": "patch",
"published_at": "2025-09-28T16:48:42Z"
},
{
"tag": "v1.1.2",
"kind": "patch",
"published_at": "2025-09-28T16:25:54Z"
},
{
"tag": "v1.1.1",
"kind": "patch",
"published_at": "2025-09-16T18:17:57Z"
},
{
"tag": "v1.1.0",
"kind": "minor",
"published_at": "2025-09-14T17:49:22Z"
},
{
"tag": "v1.0.5",
"kind": "patch",
"published_at": "2025-08-15T19:08:59Z"
},
{
"tag": "v1.0.4",
"kind": "patch",
"published_at": "2025-08-15T17:24:18Z"
},
{
"tag": "v1.0.3",
"kind": "patch",
"published_at": "2025-07-23T18:29:29Z"
},
{
"tag": "v1.0.2",
"kind": "patch",
"published_at": "2025-07-07T18:50:26Z"
},
{
"tag": "v1.0.1",
"kind": "patch",
"published_at": "2025-06-01T06:05:56Z"
},
{
"tag": "v1.0.0",
"kind": "major",
"published_at": "2025-04-25T09:52:55Z"
}
],
"recent_commits": [
{
"oid": "d1d81a404958a9a5e0f92f4fbddcca4762cd82d3",
"body": "…d facades\n\nThe paid-order activation saga's domain stages move out of the queue:\nsubscription.FulfillPaidOrder applies the order's business effect (new\npurchase with quota/single-mode enforcement, renewal, traffic reset)\nin the fulfillment transaction with its inbox marker and post-commit\ncache inv\n[…]\non uses, with the real modules\nwired over the fake store. The commission recipient's identity-cache\nrefresh is dropped — the audit established it stopped meaning anything\nonce money left the user row.",
"is_bot": false,
"headline": "refactor(billing,subscription): sink the activation saga stages behin…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T13:42:02Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "853ad4100dbeee38ca11a4ef272b991c725beb62",
"body": "…acade\n\nThe queue worker keeps only payload parsing and the skip-retry\nmapping; the grant processing (time extension, gift credit, task\nbookkeeping in one deliberate cross-domain transaction, post-commit\ncache invalidation) moves into the subscription module as the\nquotatask subdomain. The module exposes ErrQuotaTaskUnretryable\ninstead of leaking the asynq sentinel (ADR-001 step-6 preparation).",
"is_bot": false,
"headline": "refactor(subscription): sink the quota-grant task behind the module f…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T13:30:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cd88435e43910616d6ed4d4ff5b2b42c415becd3",
"body": "…cade\n\nThe queue's check-subscription worker becomes a thin shell: the\ntraffic-exceeded and expired sweeps move into the subscription module\nas a sweep subdomain (status flips in subscription transactions,\nnotification and cache invalidation as post-commit side effects,\nunchanged). The owner email lookup goes through an identity read port\nand the notices through a Notifier port that the composition root\nadapts to the email queue with runtime-read site branding (ADR-001\nstep-6 preparation).",
"is_bot": false,
"headline": "refactor(subscription): sink the lifecycle sweep behind the module fa…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T13:27:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6b57b340b3c2e9212dbf07fa839062a26f07bdb8",
"body": "The admin create-user flow now commits the account and its initial\nwallet credit in one deliberate cross-domain transaction (previously\nthree autocommit statements — a crash could leave a half-credited\naccount that retries can't repair past the email-exists check). The\npurchase quota-recheck comment\n[…]\nheduled gift grant documents its deliberate cross-domain\ntransaction, the traffic aggregator's report threshold gains a nil\nguard, and the ADR's stale generic-transaction inventory is brought\ncurrent.",
"is_bot": false,
"headline": "fix(identity),refactor: close out the audit's minor findings",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T13:13:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "df9a5a47ba5ae8b05633c828c2b3563b1281d5c3",
"body": "…dule construction\n\nFound by the post-campaign audit (high severity). The billing module\ncopied SingleModel, CurrencyUnit and the portal's SiteName/Currency\nsettings into plain fields at construction — which runs BEFORE\ninitialize.StartInitSystemConfig loads the real values from the\ndatabase, so bil\n[…]\nen the wallet read errors instead of\nrendering zero balances — the detail view feeds the admin edit form,\nso a transient error could otherwise round-trip into a real\nadjustment that zeroes the wallet.",
"is_bot": false,
"headline": "fix(billing,subscription)!: stop freezing runtime configuration at mo…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T13:11:32Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d5d8a49e73aa3d2ed7fda51192583146b32ffa99",
"body": "… detail\n\nRemoving the cross-domain Preload(\"User\") silently zeroed the admin\nGetUserSubscribeById response's user field: the reflection-based\nDeepCopy had been the hidden consumer of the association (the removal\ncommit's 'no consumer read it' claim missed it). The detail now\ncomposes the owner at the module layer through the identity read port,\nwhich is the split-friendly shape the preload removal wanted. Found by\nthe post-campaign audit.",
"is_bot": false,
"headline": "fix(subscription): restore the owner object on the admin subscription…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T13:04:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e7660170a810905a035cb0f72135c89ae8627eb6",
"body": "…ions\n\nThe monthly/first/yearly traffic resets only touch subscription-domain\nrepositories and the daily traffic-stat ranking only reads network\ntraffic and writes audit logs, so both drop the generic InTx for their\nscoped variants.",
"is_bot": false,
"headline": "refactor(queue): narrow the traffic workers to domain-scoped transact…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:51:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ece9a3b81af5db2c5d61d32960b865b6c381fb67",
"body": "The wallet entity, admin view overlays, profile policy port and the\nbilling facade all described transition states that already ended\n(dual-writes, the pre-split wallet columns, the legacy register\npolicy); their comments now describe the settled design. The admin\nbasic-info edit's generic transacti\n[…]\nerate\ntwo-domain admin convenience rather than an expired exception, and the\nportal balance payment narrows from the generic transaction to the\nbilling-scoped one (orders, wallet and audit logs only).",
"is_bot": false,
"headline": "refactor(billing),docs: sweep the stale transition comments",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:50:43Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f69a407c489fd044dd08cd3edfc585dad6b79450",
"body": "… prep\n\nThree stale baseline entries for already-deleted logic directories\ndrop, leaving 48. Everything left is composition-root or transport by\nnature (cmd, initialize, the server assembly, thin handlers,\nmiddleware/route/httpserver, the queue workers and the scheduler), so\nstep 3's shrink is declared complete; sinking the queue orchestrations\nbehind module facades and dissolving the shared repository package are\nrecorded as step-6 preparation work.",
"is_bot": false,
"headline": "docs(adr),test(arch): declare the svc-baseline floor and stage step-6…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:46:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "efaca032af34365cbb7c6313bacb77c60d4391e5",
"body": "…tions\n\nThe purchase transaction upgrades from the generic InTx to the\nbilling-scoped transaction: the per-user quota re-check reads the\nsubscription domain through the module port instead of the shared\nstore view (the wallet row lock already serialises a user's concurrent\npurchases, so the fresh re\n[…]\nto exactly what it uses —\nbilling transactions, the wallet view, and the inbox +\nsubscription-scoped transaction that the inventory helpers (now on a\nconsumer-owned orderflow.Store interface) require.",
"is_bot": false,
"headline": "refactor(billing): retire the checkout subdomain's transitional excep…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:44:56Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "085ec028a27069095f03fa5b930317a10f2a3a36",
"body": null,
"is_bot": false,
"headline": "docs(adr): record step-5 completion — data ownership settled",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:39:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ae7b8d76e3b4bc98b4c2caa404cfebc5399404c0",
"body": "The endgame of ADR-001 step 5's wallet split. WalletRepo now works\npurely on the user_wallet table: FindOneForUpdate locks (and on first\nuse seeds) the wallet row and returns the wallet entity, the update\nmethods write only wallet columns, and plain/batch reads serve the\ndisplay views. Balance, Gift\n[…]\n the wallet row; the\nportal balance-payment transaction ports switch to the wallet entity.\nWallet movements no longer touch the user row, so their user-cache\ninvalidations go away with the dual-write.",
"is_bot": false,
"headline": "feat(billing)!: complete the wallet extraction — user money columns drop",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:39:17Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a08914263c2fc28c132c5094e8090ec649775479",
"body": "…et table\n\nThe self-service account view, the pre-create gift preview and the\nTelegram admin balance display join the admin views in reading the\nbilling-owned wallet table, falling back to the dual-written legacy\ncolumns when no wallet row exists yet.",
"is_bot": false,
"headline": "feat(billing,notification,identity): show wallet values from the wall…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:26:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a5a5d745f47362e24d059e5a469d71331aaece0e",
"body": "WalletRepo gains plain reads (FindWallet, FindWalletsByUserIds) and\nthe admin user detail, list and current-user views overlay their\nbalance/gift/commission from the billing-owned table instead of\ntrusting the legacy user columns (which remain the dual-written\nfallback for rows predating a first movement).",
"is_bot": false,
"headline": "feat(identity): read admin account views from the wallet table",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:23:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3cda12221311686e3e95ad252963cea161b0907f",
"body": "…read\n\nWalletRepo.FindOneForUpdate now locks the billing-owned user_wallet\nrow and composes it with a plain read of the identity profile, seeding\nthe row from the legacy columns for accounts that predate the\nbackfill. Every flow that touches both domains follows one lock order\n— wallet first, then t\n[…]\ntive.\n\nWith that, every money movement reads and locks the wallet table; the\nuser columns remain a dual-written read model for display queries\nuntil they migrate and the columns drop (ADR-001 step 5).",
"is_bot": false,
"headline": "feat(billing): make the wallet table the authoritative transactional …",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:20:34Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c084c0a06d76d5b9e6bf62d966b940a0f4cc717f",
"body": "…-writes\n\nMigration 02143 creates the billing-owned user_wallet table (user_id\nPK, balance/gift_amount/commission) and backfills it from the user\nrow. Every wallet movement now dual-writes: the wallet view's\nUpdateBalanceFields/UpdateCommission upsert the wallet row alongside\nthe legacy user columns, and account creation seeds it with the\ninitial values. Readers keep using the user row until they migrate to\nthe wallet view, after which the user columns drop (ADR-001 step 5).",
"is_bot": false,
"headline": "feat(billing): introduce the user_wallet table with transitional dual…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:15:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b3b752f777cb47b3fbf2715757696c029858fc1b",
"body": "userRepo.Update used gorm Save, so any profile/notify/rules update\ncarrying a stale in-memory user silently overwrote balance, gift and\ncommission — racing every wallet movement that had committed since the\nrow was read. Update now omits the billing-owned money columns; the\nadmin basic-info edit, th\n[…]\n that legitimately adjusts them,\nwrites the wallet explicitly through the Wallet() view under the same\nrow lock. This also clears the path for moving the columns into their\nown table (ADR-001 step 5).",
"is_bot": false,
"headline": "fix(repository): stop full-row user saves from clobbering wallet columns",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:12:47Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "afeee6e5b7072384ff0ac51c86e6cd09f6ba29cb",
"body": "The shared *userRepo becomes three structs over one connection:\nuserRepo keeps the identity domain (accounts, auth methods, devices,\naffiliates) and the cache facade, userSubscriptionRepo owns the\nuser_subscribe rows with traffic accounting and sweeps, and\nuserBillingRepo owns the wallet-column view\n[…]\n gift\ndeduction) now go through the Wallet() view, which joins the Store\ninterface for the transition. User deletion turns out to be a soft\ndelete of the user row only, so no cascade blocks the split.",
"is_bot": false,
"headline": "refactor(repository): physically split the user repository by domain",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:10:08Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "394acb1313e29530b5a07b9380e12ad142c74636",
"body": "internal/repository/user.go (1812 lines, 87 methods on one struct)\nsplits into user_identity.go (accounts, auth methods, devices,\naffiliates, admin queries), user_subscription.go (user_subscribe rows,\ntraffic accounting, expiry/reset sweeps) and user_billing.go (the\nwallet column view and withdrawal\n[…]\nstruct, the\ninterfaces and the cache plumbing. Pure movement — the struct split\nfollows once the cross-domain cascades (Delete, BatchDeleteUser,\nBatchClearRelatedCache) are untangled (ADR-001 step 5).",
"is_bot": false,
"headline": "refactor(repository): file-split the user repository along domain seams",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:03:53Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "60193c04403973d914937411c9f9585dd5d943f4",
"body": "…n details\n\nNo consumer read SubscribeDetails.User — every caller resolves the\naccount through UserId when it needs identity data — so the cross-\ndomain Preload goes away. The remaining Subscribe preload is a\nsame-domain association. This closes appendix A.4's cross-domain SQL\ninventory; what remains of step 5 is the userRepo physical split and\nthe wallet-column extraction.",
"is_bot": false,
"headline": "refactor(repository): stop preloading the identity row on subscriptio…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:01:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f4adeed2ab797968247625b9bee6b5b04a7ad5b7",
"body": "The order repository preloaded the subscription domain's plan row into\norder details via a gorm association. The three Preload(\"Subscribe\")\nsites are gone: the user-order queries now fill the plan fields through\nthe module's PlanReader port (with a per-request cache and the old\nassociation's missing-plan semantics), the admin list never used the\nplan, and the id-based details lookup only needed its billing-domain\nsub-orders. Appendix A.4's cross-domain SQL inventory is now clear.",
"is_bot": false,
"headline": "refactor(billing): attach order plan details through the module port",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T12:00:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "521524e8a0c200a7599fa9246fc0e6770443b8cf",
"body": "…main SQL\n\nThe daily/monthly user statistics joined identity registrations with\nbilling order-user subqueries in one statement. Registrations and the\ntwo distinct-user order counts now run as separate single-domain\nqueries merged in Go, preserving the original bucket semantics (order\ncounts only surface on buckets that had registrations). Appendix A.4\nitems done; next is the userRepo physical split.",
"is_bot": false,
"headline": "refactor(repository): merge user statistics in Go instead of cross-do…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:57:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d22f08993bc4da0fccc180075379bff38e7e6ca7",
"body": "…in seam\n\nThe marketing recipient query joined identity tables (user,\nuser_auth_methods) with the subscription domain's user_subscribe in one\nSQL statement. It now resolves the subscription half first (distinct\nuser IDs by status scope) and applies the ID list to the identity-side\nquery, so no SQL crosses the domain boundary and the two halves fall\napart naturally when the user repository physically splits (ADR-001\nstep 5, appendix A.4).",
"is_bot": false,
"headline": "refactor(repository): split the email-recipient filter along the doma…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:56:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "800d48c8d26d0d615a11557999c17dfce822408b",
"body": "The ADR's step-5 section now carries the definitive table-to-module\nownership map (wallet columns earmarked for extraction from the user\nrow; audit log and inbox stay exempt shared tables). First cleanup\nfrom appendix A.4: the plan repository's user-subscribe cache-key\nlookup goes through the owning entity model instead of a raw\ntable-name query.",
"is_bot": false,
"headline": "docs(adr),refactor(repository): open step 5 with the table-ownership map",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:53:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "23e30d31eb499815b8214b86640c9a1db32b0e41",
"body": null,
"is_bot": false,
"headline": "docs(adr): record step-4 completion — the legacy logic tree is gone",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:51:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "72011aa6682b5e19c0a721b7b6f5909ae19e2b37",
"body": "…al/logic\n\nMove the Telegram bot logic into internal/module/notification as its\nfirst channel: HandleTelegramUpdate serves both the webhook handler\nand the polling loop (the duplicated composition helpers in\ninitialize/ and handler/ collapse into the facade), NotifyTelegramUnbind\nreplaces the Servic\n[…]\not.go/admin_check.go helpers are deleted rather than migrated.\n\ninternal/logic is now empty and removed: every domain lives behind a\nmodule facade. The telegram entry leaves the svc-importer baseline.",
"is_bot": false,
"headline": "feat(notification): build the notification module and dissolve intern…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:50:47Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7d4c3a9b23144c6073609f7cc57a4ecc346b815d",
"body": "Move internal/logic/admin/tool into the platform module as the tool\nsubdomain: system log tail (logger path injected), version info, IP\ngeolocation (GeoIP reader as a nil-safe closure) and process restart\n(reusing the module's Restart dependency).\n\nAlso wire the publicinfo dependencies (FullStore/Re\n[…]\ncConfig)\ninto newPlatformModule — the previous commit added the subdomain but\nits composition-root wiring never landed, which would have made the\npublic endpoints panic on nil dependencies at runtime.",
"is_bot": false,
"headline": "feat(platform): absorb the admin tools and repair the publicinfo wiring",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:47:24Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "21c02f518df594e8fff5bd664dec03f351566280",
"body": "Move internal/logic/admin/authMethod into the identity module as the\nauthmethodadmin subdomain: method configuration, sender platform\ncatalogues and email/SMS test sends. The sender platforms reach the\nmodule as a runtime snapshot, and the post-update subsystem reload\ngoes through the existing ReinitSubsystem dispatcher (which gains\nemail/mobile/device cases) instead of calling initialize directly.",
"is_bot": false,
"headline": "feat(identity): absorb the auth-method administration",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:45:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9ea669e53569897016d8d5301cbfc6a13376cd0a",
"body": "Move internal/logic/admin/application into the subscription module as\nthe application subdomain: subscribe-client CRUD and the delivery\ntemplate preview (which reads nodes through the module's existing\nnetwork-domain view).",
"is_bot": false,
"headline": "feat(subscription): absorb the client-application management",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:42:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a311fd84e9078504332a84c8400a6675c60b1f3e",
"body": "Move internal/logic/{admin/server,server,edge,nodeconfig} into\ninternal/module/network as four subdomains: adminserver (server/node\nCRUD, sorting, protocol and node-config overrides), serverapi (the\nnode-facing config/user-list pulls with ETag negotiation and the\nstatus/online/traffic pushes), edge \n[…]\n.\n\nWith this move the legacy logic tree has no cross-package imports left:\nthe frozen legacyLogicImports baseline is empty, and the four package\ndirectories leave the svc-importer baseline (55 -> 51).",
"is_bot": false,
"headline": "feat(network): build the network module",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:39:57Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "dd1553cf004dfa821ad811c6200f8811584a2e36",
"body": "The aggregator only needs the store, Redis, the runtime-mutable\ntraffic-report threshold and the node multiplier, so it now declares\nexactly that. This frees it from the svc import (baseline shrinks) and\nlets the upcoming network module use it directly without a cycle\nthrough the composition root.",
"is_bot": false,
"headline": "refactor(trafficagg): inject dependencies instead of ServiceContext",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:35:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "72a635f49393f0e3066fb94b01c5d59c18da4809",
"body": "The seven remaining public endpoints split by owning domain: global\nconfiguration, ToS/privacy, aggregate stats, client downloads and the\nheartbeat become the platform module's publicinfo subdomain (full-store\nread surface plus a runtime public-configuration snapshot), and the\npublic ads listing joins the support module's ads subdomain as\nGetPublicAds. internal/logic/common is gone, so its svc-importer\nbaseline entry goes with it.",
"is_bot": false,
"headline": "feat(platform,support): dissolve the legacy common logic package",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:30:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "527e7fb6b19f64a29ff89221ba987ddc014691a7",
"body": "Move the email/SMS code issuing and the pre-check endpoint from\ninternal/logic/common into internal/module/identity/internal/verifycode.\nThe send flows keep their explicit Dependencies structs; the subdomain\nservice builds them per request from a runtime configuration snapshot\nand feeds the register policy in from the authentication subdomain,\nwhich retires the transitional Identity.AuthPolicy() facade method.",
"is_bot": false,
"headline": "feat(identity): absorb the verification-code flows",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:26:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9829c02eeae4dcab1068794b20f38289c5277969",
"body": "Move internal/logic/auth (credential/telephone/device login and\nregistration, password resets, the OAuth handshakes and the register\npolicy) into internal/module/identity/internal/authn. The flows keep\ntheir per-flow Dependencies structs from the earlier DI refactor; the\nsubdomain service builds the\n[…]\nsenders reach\nthe policy through the transitional Identity.AuthPolicy() facade\nmethod until they migrate too. Login turnstile checks and client\nIP/user-agent extraction stay in the transport handlers.",
"is_bot": false,
"headline": "feat(identity): absorb the authentication flows",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:23:18Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ac0c64e30168df54b5b37233114235005b50fd75",
"body": "Move the sixteen public/user profile endpoints (account info, password,\nnotify/rules settings, login log, devices, OAuth and Telegram binding,\nemail/mobile rebinding and verification) into\ninternal/module/identity/internal/profile; the handlers call\nsvcCtx.Identity directly and internal/logic/public\n[…]\nrt server (both live in\nlegacy packages that import svc), the email domain-suffix policy and\nbot name become runtime config snapshots, and device unbinding upgrades\nto the identity-scoped transaction.",
"is_bot": false,
"headline": "feat(identity): absorb the self-service profile slice",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:14:52Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4082b9b686f83d36a08ff384cdb0ac833692f3c1",
"body": "…rification\n\nThe save/validate/delete helpers only depend on config and Redis, but\nliving inside internal/logic/common meant a module could not consume\nthem without importing the logic layer (which the arch tests forbid).\nThe neutral package unblocks moving the public/user account-binding\nflows into the identity module.",
"is_bot": false,
"headline": "refactor(common): hoist verification-code primitives into internal/ve…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:06:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a435bfc79e8e291ded95a22a9d0e62f6e9ffd841",
"body": "Move the six public/user wallet endpoints (commission withdrawal,\nbalance/commission/withdrawal statements, affiliate overview and list)\ninto internal/module/billing/internal/wallet. The withdrawal\ntransaction upgrades from the generic InTx to the billing-scoped\nInBillingTx and debits commission through the Wallet() view; the\nreferral tree and login identifiers are read through AffiliateReader /\nAuthMethodReader ports that the legacy user repository satisfies\nstructurally.",
"is_bot": false,
"headline": "feat(billing): absorb the user wallet slice",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T11:01:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "386ee1459fd697d9696ea5f33373b03db1dd9827",
"body": "Move the six public/user self-subscription endpoints (query, token\nreset, subscribe log, note update, pre-unsubscribe, unsubscribe) into\ninternal/module/subscription/internal/selfsub, along with the\nremaining-amount helper and the refund-authorization and admin-created\ncancellation tests. The facade\n[…]\nmin usersub variant), and\nthe handlers call svcCtx.Subscription directly.\n\ninternal/logic/public/user keeps its billing- and identity-facing\nslices, so it stays in the arch baselines until it empties.",
"is_bot": false,
"headline": "feat(subscription): absorb the self-service subscription slice",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T10:57:08Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "abb2e838aa7b9c4bed21530d5997df37bb24ca16",
"body": "…ment by domain\n\nThe admin user surface splits along its real domain boundary: the\ntwelve user-subscription endpoints join the subscription module's new\nusersub subdomain (single-subscription mode injected, policy test\nmigrated), while account CRUD, auth methods, devices and login logs\nform the iden\n[…]\nkicking behind\na callback. The profile edit keeps a documented generic transaction:\nit writes profile fields and wallet columns on the same user row until\nthe wallet table splits out (ADR-001 step 5).",
"is_bot": false,
"headline": "feat(identity): start the identity module and split admin user manage…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T10:48:23Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "efc06f87f0d4d4082ff371562b4c431cb4564925",
"body": "Token-authenticated client-config rendering, the notice placeholders\nfor expired or exhausted subscriptions and the user-agent allowlist\ngate move behind the subscription facade; the runtime-mutable delivery\nconfiguration (subscribe domain, profile interval, UA list, gateway\nmode) is read per request through a snapshot closure. The legacy\nsubscribe logic package is gone.",
"is_bot": false,
"headline": "feat(subscription): absorb the subscription delivery flow",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T10:42:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "39fbf1980e7b987cf254cbf5e89015be239c6944",
"body": "…front\n\nPlan/group management (scoped subscription transactions, device\nbroadcast through the NotifyPlanChanged callback) and the public plan\nand node listings (runtime-mutable trial plan through the IsTrialPlan\nclosure) move behind the fourth module facade; both legacy subscribe\nlogic packages are gone.",
"is_bot": false,
"headline": "feat(subscription): start the subscription module with plan and store…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T10:39:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9b88c259014665678a96944dade94aeac776c3ae",
"body": "The four reporting aggregates move behind the platform facade; every\ncross-domain access is a read-only port satisfied structurally by the\nlegacy repositories, and the snapshot cache arrives as a narrow Redis\nport. The legacy console logic package is gone.",
"is_bot": false,
"headline": "feat(platform): absorb the admin console dashboard",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T10:35:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0690be997e171e6ae3517150f68001b9d4c51c00",
"body": "Twenty-six configuration endpoints move behind the platform facade.\nRuntime side effects arrive as injected callbacks: subsystem\nre-initialization dispatches through ServiceContext.ReinitSubsystem\n(assigned by the transport server next to Restart, sidestepping the\ninitialize/svc import cycle), subscribe-path changes trigger the\nrestart hook, and the verify snapshot and node multiplier are reached\nthrough closures instead of the ServiceContext.",
"is_bot": false,
"headline": "feat(platform): absorb the system configuration subdomain",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T10:33:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "abbbb354044fbf33b2dbc2076977cae1fbb091ef",
"body": "Fifteen audit/message-log endpoints and the log retention settings\nmove behind the new platform facade; the runtime-mutable retention\nconfiguration is read and propagated through injected callbacks\ninstead of touching the ServiceContext, and the PlatformStore view\nwith InPlatformTx completes the domain-scoped transaction family. The\nlegacy admin log logic package is gone.",
"is_bot": false,
"headline": "feat(platform): start the platform module with the audit log subdomain",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T10:26:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9f087176945bbf23b0806a934f529b824720bd7c",
"body": "The 42-line public payment logic duplicated the portal subdomain's\navailable-methods listing; the handler now calls the existing facade\nmethod and the legacy package is gone.",
"is_bot": false,
"headline": "refactor(billing): route public payment methods through the facade",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T10:22:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3add94f9fa68675db92a8ffecfb9886307c3d53a",
"body": "Idempotent create-and-checkout, guest checkout capabilities and the\nSSE event-stream tickets move into the module as the v2 subdomain,\ninvoking the checkout and portal subdomains directly instead of going\nback through the facade. V2AuthorizeEventStream folds ticket\nauthorization, expiry and the initial snapshot into one facade call so\nthe order entity never leaves the module, and the emptied\ninternal/logic/public/order package is gone.",
"is_bot": false,
"headline": "feat(billing): absorb the V2 order orchestration",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T10:21:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8ef0d68606946b93f0c1ea5d64644b8552ecab93",
"body": "The callbacks subdomain authenticates EPay/Stripe/Alipay\nnotifications, verifies them against the order's immutable payment\nexpectation, re-confirms with the gateway and settles through the\nmodule's shared settle primitive — one implementation now serves both\ncallback and expiry-time settlement so their semantics cannot drift.\nThe legacy notify logic package is gone and the svc-import baseline\nshrinks again.",
"is_bot": false,
"headline": "feat(billing): absorb the payment gateway callbacks",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T10:09:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fa0ec7ea94d8dcbc9291a0e103e34062fbec51eb",
"body": "The portal subdomain takes over guest pre-orders, the gateway/balance\ncheckout (whose hexagonal CheckoutDependencies move verbatim, with\ngateway-mode detection injected instead of read from a global), order\nstatus polling with the session exchange, and the storefront listings.\nV2 orchestration now reaches purchase, checkout and session issuance\nthrough the facade, the legacy portal logic package is gone, and both\narchitecture baselines shrink accordingly.",
"is_bot": false,
"headline": "feat(billing): absorb the guest portal storefront",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T10:00:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "301d2b4956f11ac76847291ee88ae9a94459fd0b",
"body": "Purchase, renewal, traffic reset, recharge, order preview and close\nmove behind the billing facade as the checkout subdomain. Subscription\nreads arrive through PlanReader/UserSubscriptionReader ports satisfied\nstructurally by the legacy repositories, the order queue port gains\ndeferred-close schedul\n[…]\nn logic instead of reaching\ninto the notify package. Renewal and traffic-reset transactions run on\nthe billing-scoped store; V2 orchestration and the queue's close-order\ncallers go through the facade.",
"is_bot": false,
"headline": "feat(billing): absorb the checkout money flows",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T09:48:13Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d517d34b90b948d765f38a6773f603a50245f988",
"body": "Coupon CRUD (with validation and the used-count immutability guard)\nand the user-facing order queries (ownership check, commission\nscrubbing) move behind the billing facade; the admin coupon logic\npackage is gone and internal/logic/public/order shrinks to the checkout\nflows. The svc-import baseline loses the migrated package.",
"is_bot": false,
"headline": "feat(billing): absorb coupon management and user order queries",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T09:32:01Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a31f5849b8dc8188fe3775d9f58f86062e1e5662",
"body": "The 71-directory baseline may only shrink: new packages must receive\ndependencies through module facade constructors instead of reaching for\nthe ServiceContext god object, making the ADR-001 step-3 shrink\nmeasurable and one-way.",
"is_bot": false,
"headline": "test(arch): freeze the set of packages importing internal/svc",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T09:25:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "88aea8be2e977248dac02794812307b8e1cdbde9",
"body": "…gement\n\nThe billing module facade takes over admin order creation/listing, the\nPending->Paid/Closed state machine (with activation enqueueing behind\nan ActivationEnqueuer port) and payment-method management; gateway-mode\ndetection and the site host arrive as injected dependencies instead of\nglobals. The legacy logic packages are removed and their handlers call\nthe facade (ADR-001 steps 3+4 for the billing domain).",
"is_bot": false,
"headline": "feat(billing): start billing module with admin order and payment mana…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T09:23:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a8b3c33b00ace4028ee848c6853298a97fa23033",
"body": "BillingStore, SubscriptionStore, IdentityStore and NetworkStore narrow\nwhat a transaction closure can touch, so a cross-domain write inside a\nsingle-domain transaction no longer compiles; WalletRepo materialises\nthe wallet-belongs-to-billing clarification. All transactions produced\nby the step-2 decomposition now run on the scoped variants; the two\ndocumented transitional exceptions (fulfillment user lock, purchase\nquota read) stay on the generic InTx.",
"is_bot": false,
"headline": "feat(repository): add domain-scoped store views and transactions",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T09:16:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "740e5c2abd664ed56fb4fb54bc08d09c4c8caea6",
"body": "…in transactions\n\nUnsubscribe now cancels in a subscription-domain transaction that\nrecords the owed refund in the idempotent inbox, then settles it in a\nbilling-domain transaction; a crash between the two resumes at the\nrefund stage on retry. Traffic bucket flushes likewise commit the\nsubscription \n[…]\nand the network traffic log separately,\nkeyed by the bucket suffix so pipeline replays cannot double-count the\nhalf that already committed. Inbox markers age out with the existing\n30-day cleanup task.",
"is_bot": false,
"headline": "refactor(order): split unsubscribe refund and traffic flush into doma…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T09:07:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "00ce31b336b5348b208872ae76b77e87ef74d748",
"body": "… transactions\n\nPurchase and portal purchase now create the order in a pure billing\ntransaction and reserve plan inventory in a separate\nsubscription-domain transaction keyed by order number in the\nidempotent inbox; a failed reservation closes the order, which releases\nthe coupon and gift deduction \n[…]\nk that\nwas never taken. Close-order likewise restores inventory after its\nbilling CAS commits, exactly once, and resumes a lost restoration when\nthe close task retries against an already-closed order.",
"is_bot": false,
"headline": "refactor(order): move plan inventory lifecycle to subscription-domain…",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T09:01:59Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6ec44002add0a25d0aaafc8407e05b0707f46349",
"body": "The subscription check task now commits the traffic/expiry status flip\nin a pure subscription-domain transaction; notifications and cache\ninvalidation run after the commit as retryable side effects. Also\nrecords the ADR-001 wallet-belongs-to-billing clarification that\nreclassifies six balance-movement transactions as single-domain.",
"is_bot": false,
"headline": "refactor(subscription): commit status flips before side effects",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T08:56:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "58b7c1b9e61e7ea8c97fcb39dff1a1d6eb35f595",
"body": "Order activation no longer runs one transaction across billing,\nsubscription, identity and platform. Each stage (guest account,\nfulfillment, commission, settlement) commits in its owning domain and\nmarks itself in the idempotent inbox, so at-least-once deliveries and\npaid-order reconciliation replay\n[…]\nf\ndouble-applying them. The order stays Paid until the billing settlement\ncommits the Paid -> Finished CAS together with the order.fulfilled\noutbox event, preserving the durable reconciliation signal.",
"is_bot": false,
"headline": "refactor(order): split activation into per-domain transactions",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T08:49:21Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c0bd3706883895b3609bf1828e77e1a430fd8a6c",
"body": "The domain_event_inbox table lets each domain step mark an event as\nprocessed inside its own transaction (inbox pattern, ADR-001 step 2),\nmaking at-least-once deliveries and reconciliation replays safe once\ncross-domain transactions are split apart.",
"is_bot": false,
"headline": "feat(repository): add domain event inbox for idempotent consumers",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T08:44:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5e42b61d4177265ba6defbfc68ca46c0070df29c",
"body": "The non-transactional NewPurchase/Renewal/ResetTraffic/Recharge flow\nhas no callers since activation moved into a single transaction; the\ntransactional path and its shared helpers remain.",
"is_bot": false,
"headline": "refactor(order): drop unused legacy activation path",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T08:40:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "35db1ad696e7b3a4c30cf56b26d0a3819ab49fd6",
"body": "Campaign orchestration now depends on module-owned ports: the legacy\nuser and user-subscription repositories satisfy the recipient and\nquota-target ports structurally, while asynq enqueueing and the batch\nemail worker manager are adapted in the composition root so queue task\ntypes and the global worker stay out of the module.",
"is_bot": false,
"headline": "refactor(support): move marketing domain into support module",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T08:32:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "afe955ffa5c0499a0d7ee055ad2abfcdae6167f0",
"body": "Admin and user ticket flows now live in one subdomain service;\nownership checks and status transitions are unchanged and covered by\nfacade-level tests.",
"is_bot": false,
"headline": "refactor(support): move ticket domain into support module",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T08:23:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2c1dd581ec3b26c30d1ed88977609767f104b6c6",
"body": "The public document detail's subscription-gated rendering now depends\non a SubscriptionReader port owned by the support module; the\ncomposition root adapts the legacy user-subscription repository until\nthe subscription module exists (ADR-001).",
"is_bot": false,
"headline": "refactor(support): move document domain into support module",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T08:19:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a8a6ebd37d30160a334ab45506ce03fd19a178db",
"body": null,
"is_bot": false,
"headline": "refactor(support): move ads domain into support module",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T08:15:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "131e9b8ab241c3fab9c8c513ed5842a50d4aad64",
"body": "Pilot for ADR-001: the announcement domain now lives behind the\nsupport module facade (internal/module/support) with its\nimplementation sealed under the module's internal/ tree. Admin and\npublic handlers call the same service through ServiceContext, which\nacts as the composition root; the legacy logic packages are removed.",
"is_bot": false,
"headline": "refactor(support): move announcement domain into support module",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T08:13:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "068ca14d83b2a3abb31877104cd9161dc23f3bb0",
"body": null,
"is_bot": false,
"headline": "refactor(repository): remove unused Store.DB escape hatch",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T08:13:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ee9a4c820262a03a4b7399433d72d1f9e9e0ace7",
"body": null,
"is_bot": false,
"headline": "docs: add modular monolith ADR and architecture boundary tests",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T08:13:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3aee6fe61e281e6b6ee78baec2d087946bef1db0",
"body": null,
"is_bot": false,
"headline": "fix(epay): fall back to EasyPay order query",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T04:45:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "de67ff265ed3ddf0c12fcbafa97676b514d04d23",
"body": null,
"is_bot": false,
"headline": "fix(order): preserve null idempotency keys on updates",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-24T04:26:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "81be38f1454550096124918adb6393ed869a4bfd",
"body": null,
"is_bot": false,
"headline": "feat(epay): add mapi checkout mode",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T14:41:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a02a0593f9aa7bcba062ea6b63b1a68478392369",
"body": null,
"is_bot": false,
"headline": "fix(order): distinguish renewal previews from new-purchase quota checks",
"author_name": "hainingning",
"author_login": "hainingning",
"committed_at": "2026-07-23T14:10:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7f670b28bab251fd823077002200773874d7e88e",
"body": null,
"is_bot": false,
"headline": "feat(order): add v2 checkout events and session flow",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T14:03:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6ed7775fdf32be5e34ee45f2017135619329170b",
"body": null,
"is_bot": false,
"headline": "fix: make checkout retries idempotent",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T12:57:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bcc06a16d72c591f7fcd95139e5bf7ca1ed1ece6",
"body": null,
"is_bot": false,
"headline": "fix: prevent reset traffic on expired subscriptions",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T12:50:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "45519f191a27dfbf43aaa68eef286ff7b43c934d",
"body": null,
"is_bot": false,
"headline": "refactor: inject telegram command dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T08:22:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "498c26f39ccd266923abf9c1a7774092954bb065",
"body": null,
"is_bot": false,
"headline": "refactor: inject sms code dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T08:17:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cf998c78672bb5d859b63a5b78eeb8e38c55d2b3",
"body": null,
"is_bot": false,
"headline": "refactor: inject email code dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T08:15:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f9b5121c287a578c570f585c66526a452fe920a0",
"body": null,
"is_bot": false,
"headline": "refactor: inject global config dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T08:12:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "85284551cb1523da6aa53d509df838f2f5f6c364",
"body": null,
"is_bot": false,
"headline": "refactor: inject account check dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T08:10:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5ac28dbbe0a2f46025f266b3c1260619095f5b36",
"body": null,
"is_bot": false,
"headline": "refactor: inject apple oauth callback dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T08:08:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ae39a921e99613e3f3435f91a20f7c92abb35667",
"body": null,
"is_bot": false,
"headline": "refactor: inject oauth login url dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T08:06:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "66b4e31f23ea6261a019a2a5ab7803281b19663e",
"body": null,
"is_bot": false,
"headline": "refactor: inject device binding dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T08:04:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "82e9947bf2fd92ba16192caf5daebbfc9f7ad5c2",
"body": null,
"is_bot": false,
"headline": "refactor: inject telephone password reset dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T08:02:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "076d758d874e69bb2a9ad0fc72c5a1f6983bcbdc",
"body": null,
"is_bot": false,
"headline": "refactor: inject email password reset dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T08:00:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "90b0c5358dfb4ec037cc1260b8f85b2ee1d014cc",
"body": null,
"is_bot": false,
"headline": "refactor: inject email login dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T07:55:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "267d3d6008b8c190441d0f6c846c85c43bca5218",
"body": null,
"is_bot": false,
"headline": "refactor: inject telephone login dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T07:54:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9c1b9811022e3e9482671a9346f7e82d2d77349a",
"body": null,
"is_bot": false,
"headline": "refactor: inject telephone registration dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T07:51:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "433d5f398a99b3c37abc84cecaddfa69e263510c",
"body": null,
"is_bot": false,
"headline": "refactor: inject email registration dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T07:48:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9e5a1702b0b997acf7aa5d8712e4f25b5a977b7b",
"body": null,
"is_bot": false,
"headline": "refactor: inject device login dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T07:44:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ad38f061b012399120446383b0f4e84b52ce8498",
"body": null,
"is_bot": false,
"headline": "refactor: inject oauth bind callback dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T07:41:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fa055538ccff0efe74eb72ac25c2511f29cd60db",
"body": null,
"is_bot": false,
"headline": "refactor: inject oauth login dependencies",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T07:38:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "99acb73c2d0c0701014edb2666cb38d8a1c62d07",
"body": null,
"is_bot": false,
"headline": "refactor: isolate telegram admin commands",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T07:34:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cfcbe75de030b61773e2e34b7cbdd9bf42c21b22",
"body": null,
"is_bot": false,
"headline": "refactor: split user repository by domain",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T07:27:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dc1ce954e3b73894d23465126f78df68ee0a2941",
"body": null,
"is_bot": false,
"headline": "refactor: inject checkout dependencies explicitly",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T07:21:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6e8170c3736c6e37c3862744eda3eeaaeeabb87f",
"body": null,
"is_bot": false,
"headline": "refactor: remove plugin runtime and decouple packages",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T07:12:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "16340d97deca306963d08496f24081ba4a5aa755",
"body": null,
"is_bot": false,
"headline": "chore(swagger): sync password constraints",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T06:42:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a78b3dedbf989de2b860215d62ac12c46353c43f",
"body": null,
"is_bot": false,
"headline": "fix(subscription): align visibility and quota rules",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T06:38:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a0964bb2a1739c06fa4e85d4ea0e52027c725501",
"body": null,
"is_bot": false,
"headline": "feat(auth): migrate password hashes to argon2id",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-23T06:12:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "14d4125202670c472a308aa0529687a9066e455f",
"body": null,
"is_bot": false,
"headline": "Update ppanel.json",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-22T18:53:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "78af2ffacb5db8736493dfb1f5249fa50b0449a7",
"body": null,
"is_bot": false,
"headline": "fix: harden payment and order settlement",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-22T18:50:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9b8290c7f1b0aec2861b394657a6fdb05d186cff",
"body": null,
"is_bot": false,
"headline": "remove: drop CryptoSaaS payment support",
"author_name": "Ember Moth",
"author_login": "Ember-Moth",
"committed_at": "2026-07-22T18:06:32Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 89,
"commits_last_year": 410,
"latest_release_at": "2026-07-24T13:17:58Z",
"latest_release_tag": "v1.15.0",
"releases_from_tags": false,
"days_since_last_push": 0,
"active_weeks_last_year": 33,
"days_since_latest_release": 0,
"mean_days_between_releases": 0.2
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 37,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "github.com/perfect-panel/server",
"exists": true,
"license": null,
"keywords": [],
"ecosystem": "go",
"matches_repo": false,
"registry_url": "https://pkg.go.dev/github.com/perfect-panel/server",
"is_deprecated": false,
"latest_version": "v1.15.0",
"repository_url": "https://github.com/perfect-panel/server",
"versions_count": 90,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": null,
"latest_published_at": "2026-07-24T13:13:55Z",
"latest_version_yanked": null,
"days_since_latest_publish": 0
}
]
},
"popularity": {
"forks": 91,
"stars": 137,
"watchers": 2,
"fork_history": {
"days": [
{
"date": "2025-04-25",
"count": 3
},
{
"date": "2025-04-26",
"count": 2
},
{
"date": "2025-04-28",
"count": 3
},
{
"date": "2025-05-03",
"count": 1
},
{
"date": "2025-05-07",
"count": 1
},
{
"date": "2025-05-13",
"count": 1
},
{
"date": "2025-05-22",
"count": 2
},
{
"date": "2025-05-27",
"count": 1
},
{
"date": "2025-05-30",
"count": 1
},
{
"date": "2025-05-31",
"count": 1
},
{
"date": "2025-06-01",
"count": 1
},
{
"date": "2025-06-02",
"count": 1
},
{
"date": "2025-06-03",
"count": 1
},
{
"date": "2025-06-07",
"count": 1
},
{
"date": "2025-06-12",
"count": 1
},
{
"date": "2025-06-26",
"count": 1
},
{
"date": "2025-07-07",
"count": 1
},
{
"date": "2025-07-12",
"count": 2
},
{
"date": "2025-07-15",
"count": 1
},
{
"date": "2025-07-19",
"count": 1
},
{
"date": "2025-07-23",
"count": 1
},
{
"date": "2025-07-26",
"count": 1
},
{
"date": "2025-07-29",
"count": 1
},
{
"date": "2025-08-06",
"count": 2
},
{
"date": "2025-08-10",
"count": 1
},
{
"date": "2025-08-14",
"count": 1
},
{
"date": "2025-08-23",
"count": 1
},
{
"date": "2025-09-08",
"count": 1
},
{
"date": "2025-09-10",
"count": 1
},
{
"date": "2025-09-17",
"count": 1
},
{
"date": "2025-09-18",
"count": 2
},
{
"date": "2025-09-19",
"count": 1
},
{
"date": "2025-10-11",
"count": 1
},
{
"date": "2025-10-19",
"count": 1
},
{
"date": "2025-10-23",
"count": 1
},
{
"date": "2025-10-25",
"count": 1
},
{
"date": "2025-10-30",
"count": 1
},
{
"date": "2025-10-31",
"count": 1
},
{
"date": "2025-11-10",
"count": 1
},
{
"date": "2025-11-19",
"count": 2
},
{
"date": "2025-11-22",
"count": 1
},
{
"date": "2025-12-01",
"count": 1
},
{
"date": "2025-12-03",
"count": 1
},
{
"date": "2025-12-04",
"count": 1
},
{
"date": "2025-12-11",
"count": 1
},
{
"date": "2025-12-20",
"count": 1
},
{
"date": "2025-12-25",
"count": 1
},
{
"date": "2026-01-07",
"count": 1
},
{
"date": "2026-01-23",
"count": 1
},
{
"date": "2026-01-28",
"count": 1
},
{
"date": "2026-01-29",
"count": 2
},
{
"date": "2026-02-02",
"count": 1
},
{
"date": "2026-02-03",
"count": 1
},
{
"date": "2026-02-11",
"count": 1
},
{
"date": "2026-02-14",
"count": 1
},
{
"date": "2026-02-18",
"count": 1
},
{
"date": "2026-02-27",
"count": 1
},
{
"date": "2026-03-04",
"count": 1
},
{
"date": "2026-03-18",
"count": 1
},
{
"date": "2026-03-21",
"count": 1
},
{
"date": "2026-03-23",
"count": 1
},
{
"date": "2026-04-05",
"count": 1
},
{
"date": "2026-04-10",
"count": 1
},
{
"date": "2026-04-16",
"count": 1
},
{
"date": "2026-04-30",
"count": 1
},
{
"date": "2026-05-07",
"count": 1
},
{
"date": "2026-05-10",
"count": 1
},
{
"date": "2026-06-04",
"count": 1
},
{
"date": "2026-06-05",
"count": 1
},
{
"date": "2026-06-08",
"count": 1
},
{
"date": "2026-06-25",
"count": 1
},
{
"date": "2026-06-29",
"count": 1
},
{
"date": "2026-07-01",
"count": 1
},
{
"date": "2026-07-06",
"count": 1
},
{
"date": "2026-07-08",
"count": 2
},
{
"date": "2026-07-12",
"count": 1
}
],
"complete": true,
"collected": 88,
"total_forks": 91
},
"star_history": null,
"open_issues_and_prs": 3
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": true,
"has_mcp_signal": false,
"bootstrap_files": [
"Makefile"
],
"api_schema_files": [
".github/workflows/swagger.yaml",
"api/server/v1/server.proto"
],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [
"go.mod"
],
"largest_source_bytes": 68597,
"source_files_sampled": 1067,
"oversized_source_files": 1,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"go.mod"
],
"advisories": {
"error": null,
"scope": "repository_graph",
"source": "osv",
"findings": [
{
"name": "golang.org/x/crypto",
"direct": true,
"version": "v0.52.0",
"severity": "unknown",
"ecosystem": "go",
"cvss_score": null,
"advisory_ids": [
"GO-2026-5932"
],
"fixed_version": null,
"advisory_count": 1,
"oldest_advisory_days": 16
},
{
"name": "golang.org/x/net",
"direct": false,
"version": "v0.55.0",
"severity": "unknown",
"ecosystem": "go",
"cvss_score": null,
"advisory_ids": [
"GO-2026-5942"
],
"fixed_version": "0.56.0",
"advisory_count": 1,
"oldest_advisory_days": 9
},
{
"name": "golang.org/x/text",
"direct": false,
"version": "v0.37.0",
"severity": "unknown",
"ecosystem": "go",
"cvss_score": null,
"advisory_ids": [
"GO-2026-5970"
],
"fixed_version": "0.39.0",
"advisory_count": 1,
"oldest_advisory_days": 9
}
],
"collected": true,
"malicious": [],
"truncated": false,
"by_severity": {
"unknown": 3
},
"advisory_count": 3,
"affected_count": 3,
"assessed_count": 143,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 1
},
"ecosystems": [
"go"
],
"dependencies": [
{
"name": "github.com/GUAIK-ORG/go-snowflake",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.0.0-20200116064823-220c4260e85f"
},
{
"name": "github.com/alibabacloud-go/darabonba-openapi",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.1.18"
},
{
"name": "github.com/alibabacloud-go/dysmsapi-20170525/v2",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v2.0.18"
},
{
"name": "github.com/alibabacloud-go/tea",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.2.2"
},
{
"name": "github.com/alicebob/miniredis/v2",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v2.34.0"
},
{
"name": "github.com/andybalholm/brotli",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.1.1"
},
{
"name": "github.com/forgoer/openssl",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.6.0"
},
{
"name": "github.com/go-playground/locales",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.14.1"
},
{
"name": "github.com/go-playground/universal-translator",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.18.1"
},
{
"name": "github.com/go-playground/validator/v10",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v10.24.0"
},
{
"name": "github.com/go-resty/resty/v2",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v2.15.3"
},
{
"name": "github.com/go-sql-driver/mysql",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.8.1"
},
{
"name": "github.com/go-telegram-bot-api/telegram-bot-api/v5",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v5.5.1"
},
{
"name": "github.com/gofrs/uuid/v5",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v5.3.0"
},
{
"name": "github.com/golang-jwt/jwt/v5",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v5.2.2"
},
{
"name": "github.com/google/uuid",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.6.0"
},
{
"name": "github.com/gorilla/websocket",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.5.3"
},
{
"name": "github.com/hibiken/asynq",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.24.1"
},
{
"name": "github.com/jinzhu/copier",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.4.0"
},
{
"name": "github.com/klauspost/compress",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.17.9"
},
{
"name": "github.com/nyaruka/phonenumbers",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.5.0"
},
{
"name": "github.com/pkg/errors",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.9.1"
},
{
"name": "github.com/redis/go-redis/v9",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v9.7.3"
},
{
"name": "github.com/smartwalle/alipay/v3",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v3.2.23"
},
{
"name": "github.com/spf13/cobra",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.8.1"
},
{
"name": "github.com/stretchr/testify",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.11.1"
},
{
"name": "github.com/stripe/stripe-go/v81",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v81.1.0"
},
{
"name": "github.com/twilio/twilio-go",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.23.11"
},
{
"name": "go.opentelemetry.io/otel",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.43.0"
},
{
"name": "go.opentelemetry.io/otel/exporters/jaeger",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.17.0"
},
{
"name": "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.43.0"
},
{
"name": "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.43.0"
},
{
"name": "go.opentelemetry.io/otel/exporters/stdout/stdouttrace",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.43.0"
},
{
"name": "go.opentelemetry.io/otel/exporters/zipkin",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.43.0"
},
{
"name": "go.opentelemetry.io/otel/sdk",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.43.0"
},
{
"name": "go.opentelemetry.io/otel/trace",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.43.0"
},
{
"name": "go.uber.org/zap",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.27.0"
},
{
"name": "golang.org/x/crypto",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.52.0"
},
{
"name": "golang.org/x/oauth2",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.36.0"
},
{
"name": "golang.org/x/time",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.6.0"
},
{
"name": "gopkg.in/gomail.v2",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v2.0.0-20160411212932-81ebce5c23df"
},
{
"name": "gopkg.in/yaml.v3",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v3.0.1"
},
{
"name": "gorm.io/driver/mysql",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.5.7"
},
{
"name": "gorm.io/driver/sqlite",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.5.7"
},
{
"name": "gorm.io/gorm",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.25.12"
},
{
"name": "gorm.io/plugin/soft_delete",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.2.1"
},
{
"name": "github.com/Masterminds/sprig/v3",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v3.3.0"
},
{
"name": "github.com/cloudwego/hertz",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.10.4"
},
{
"name": "github.com/fatih/color",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.18.0"
},
{
"name": "github.com/goccy/go-json",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.10.4"
},
{
"name": "github.com/golang-migrate/migrate/v4",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v4.18.2"
},
{
"name": "github.com/lib/pq",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.10.9"
},
{
"name": "github.com/oschwald/geoip2-golang",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.13.0"
},
{
"name": "github.com/spaolacci/murmur3",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.1.0"
},
{
"name": "google.golang.org/grpc",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.82.1"
},
{
"name": "google.golang.org/protobuf",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.36.11"
},
{
"name": "gorm.io/driver/postgres",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.6.0"
}
],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "github.com/alibabacloud-go/darabonba-openapi",
"direct": true,
"version": "v0.1.18",
"ecosystem": "go"
},
{
"name": "github.com/alibabacloud-go/dysmsapi-20170525/v2",
"direct": true,
"version": "v2.0.18",
"ecosystem": "go"
},
{
"name": "github.com/alibabacloud-go/tea",
"direct": true,
"version": "v1.2.2",
"ecosystem": "go"
},
{
"name": "github.com/alicebob/miniredis/v2",
"direct": true,
"version": "v2.34.0",
"ecosystem": "go"
},
{
"name": "github.com/andybalholm/brotli",
"direct": true,
"version": "v1.1.1",
"ecosystem": "go"
},
{
"name": "github.com/cloudwego/hertz",
"direct": true,
"version": "v0.10.4",
"ecosystem": "go"
},
{
"name": "github.com/fatih/color",
"direct": true,
"version": "v1.18.0",
"ecosystem": "go"
},
{
"name": "github.com/forgoer/openssl",
"direct": true,
"version": "v1.6.0",
"ecosystem": "go"
},
{
"name": "github.com/go-playground/locales",
"direct": true,
"version": "v0.14.1",
"ecosystem": "go"
},
{
"name": "github.com/go-playground/universal-translator",
"direct": true,
"version": "v0.18.1",
"ecosystem": "go"
},
{
"name": "github.com/go-playground/validator/v10",
"direct": true,
"version": "v10.24.0",
"ecosystem": "go"
},
{
"name": "github.com/go-resty/resty/v2",
"direct": true,
"version": "v2.15.3",
"ecosystem": "go"
},
{
"name": "github.com/go-sql-driver/mysql",
"direct": true,
"version": "v1.8.1",
"ecosystem": "go"
},
{
"name": "github.com/go-telegram-bot-api/telegram-bot-api/v5",
"direct": true,
"version": "v5.5.1",
"ecosystem": "go"
},
{
"name": "github.com/goccy/go-json",
"direct": true,
"version": "v0.10.4",
"ecosystem": "go"
},
{
"name": "github.com/gofrs/uuid/v5",
"direct": true,
"version": "v5.3.0",
"ecosystem": "go"
},
{
"name": "github.com/golang-jwt/jwt/v5",
"direct": true,
"version": "v5.2.2",
"ecosystem": "go"
},
{
"name": "github.com/golang-migrate/migrate/v4",
"direct": true,
"version": "v4.18.2",
"ecosystem": "go"
},
{
"name": "github.com/google/uuid",
"direct": true,
"version": "v1.6.0",
"ecosystem": "go"
},
{
"name": "github.com/gorilla/websocket",
"direct": true,
"version": "v1.5.3",
"ecosystem": "go"
},
{
"name": "github.com/guaik-org/go-snowflake",
"direct": true,
"version": "v0.0.0-20200116064823-220c4260e85f",
"ecosystem": "go"
},
{
"name": "github.com/hibiken/asynq",
"direct": true,
"version": "v0.24.1",
"ecosystem": "go"
},
{
"name": "github.com/jinzhu/copier",
"direct": true,
"version": "v0.4.0",
"ecosystem": "go"
},
{
"name": "github.com/klauspost/compress",
"direct": true,
"version": "v1.17.9",
"ecosystem": "go"
},
{
"name": "github.com/lib/pq",
"direct": true,
"version": "v1.10.9",
"ecosystem": "go"
},
{
"name": "github.com/masterminds/sprig/v3",
"direct": true,
"version": "v3.3.0",
"ecosystem": "go"
},
{
"name": "github.com/nyaruka/phonenumbers",
"direct": true,
"version": "v1.5.0",
"ecosystem": "go"
},
{
"name": "github.com/oschwald/geoip2-golang",
"direct": true,
"version": "v1.13.0",
"ecosystem": "go"
},
{
"name": "github.com/pkg/errors",
"direct": true,
"version": "v0.9.1",
"ecosystem": "go"
},
{
"name": "github.com/redis/go-redis/v9",
"direct": true,
"version": "v9.7.3",
"ecosystem": "go"
},
{
"name": "github.com/smartwalle/alipay/v3",
"direct": true,
"version": "v3.2.23",
"ecosystem": "go"
},
{
"name": "github.com/spaolacci/murmur3",
"direct": true,
"version": "v1.1.0",
"ecosystem": "go"
},
{
"name": "github.com/spf13/cobra",
"direct": true,
"version": "v1.8.1",
"ecosystem": "go"
},
{
"name": "github.com/stretchr/testify",
"direct": true,
"version": "v1.11.1",
"ecosystem": "go"
},
{
"name": "github.com/stripe/stripe-go/v81",
"direct": true,
"version": "v81.1.0",
"ecosystem": "go"
},
{
"name": "github.com/twilio/twilio-go",
"direct": true,
"version": "v1.23.11",
"ecosystem": "go"
},
{
"name": "go.opentelemetry.io/otel",
"direct": true,
"version": "v1.43.0",
"ecosystem": "go"
},
{
"name": "go.opentelemetry.io/otel/exporters/jaeger",
"direct": true,
"version": "v1.17.0",
"ecosystem": "go"
},
{
"name": "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc",
"direct": true,
"version": "v1.43.0",
"ecosystem": "go"
},
{
"name": "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp",
"direct": true,
"version": "v1.43.0",
"ecosystem": "go"
},
{
"name": "go.opentelemetry.io/otel/exporters/stdout/stdouttrace",
"direct": true,
"version": "v1.43.0",
"ecosystem": "go"
},
{
"name": "go.opentelemetry.io/otel/exporters/zipkin",
"direct": true,
"version": "v1.43.0",
"ecosystem": "go"
},
{
"name": "go.opentelemetry.io/otel/sdk",
"direct": true,
"version": "v1.43.0",
"ecosystem": "go"
},
{
"name": "go.opentelemetry.io/otel/trace",
"direct": true,
"version": "v1.43.0",
"ecosystem": "go"
},
{
"name": "go.uber.org/zap",
"direct": true,
"version": "v1.27.0",
"ecosystem": "go"
},
{
"name": "golang.org/x/crypto",
"direct": true,
"version": "v0.52.0",
"ecosystem": "go"
},
{
"name": "golang.org/x/oauth2",
"direct": true,
"version": "v0.36.0",
"ecosystem": "go"
},
{
"name": "golang.org/x/time",
"direct": true,
"version": "v0.6.0",
"ecosystem": "go"
},
{
"name": "google.golang.org/grpc",
"direct": true,
"version": "v1.82.1",
"ecosystem": "go"
},
{
"name": "google.golang.org/protobuf",
"direct": true,
"version": "v1.36.11",
"ecosystem": "go"
},
{
"name": "gopkg.in/gomail.v2",
"direct": true,
"version": "v2.0.0-20160411212932-81ebce5c23df",
"ecosystem": "go"
},
{
"name": "gopkg.in/yaml.v3",
"direct": true,
"version": "v3.0.1",
"ecosystem": "go"
},
{
"name": "gorm.io/driver/mysql",
"direct": true,
"version": "v1.5.7",
"ecosystem": "go"
},
{
"name": "gorm.io/driver/postgres",
"direct": true,
"version": "v1.6.0",
"ecosystem": "go"
},
{
"name": "gorm.io/driver/sqlite",
"direct": true,
"version": "v1.5.7",
"ecosystem": "go"
},
{
"name": "gorm.io/gorm",
"direct": true,
"version": "v1.25.12",
"ecosystem": "go"
},
{
"name": "gorm.io/plugin/soft_delete",
"direct": true,
"version": "v1.2.1",
"ecosystem": "go"
},
{
"name": "cloud.google.com/go/compute/metadata",
"direct": false,
"version": "v0.9.0",
"ecosystem": "go"
},
{
"name": "dario.cat/mergo",
"direct": false,
"version": "v1.0.1",
"ecosystem": "go"
},
{
"name": "filippo.io/edwards25519",
"direct": false,
"version": "v1.1.1",
"ecosystem": "go"
},
{
"name": "github.com/alibabacloud-go/alibabacloud-gateway-spi",
"direct": false,
"version": "v0.0.5",
"ecosystem": "go"
},
{
"name": "github.com/alibabacloud-go/debug",
"direct": false,
"version": "v1.0.1",
"ecosystem": "go"
},
{
"name": "github.com/alibabacloud-go/endpoint-util",
"direct": false,
"version": "v1.1.0",
"ecosystem": "go"
},
{
"name": "github.com/alibabacloud-go/openapi-util",
"direct": false,
"version": "v0.1.1",
"ecosystem": "go"
},
{
"name": "github.com/alibabacloud-go/tea-utils",
"direct": false,
"version": "v1.4.5",
"ecosystem": "go"
},
{
"name": "github.com/alibabacloud-go/tea-utils/v2",
"direct": false,
"version": "v2.0.7",
"ecosystem": "go"
},
{
"name": "github.com/alibabacloud-go/tea-xml",
"direct": false,
"version": "v1.1.3",
"ecosystem": "go"
},
{
"name": "github.com/alicebob/gopher-json",
"direct": false,
"version": "v0.0.0-20230218143504-906a9b012302",
"ecosystem": "go"
},
{
"name": "github.com/aliyun/credentials-go",
"direct": false,
"version": "v1.3.10",
"ecosystem": "go"
},
{
"name": "github.com/bytedance/gopkg",
"direct": false,
"version": "v0.1.3",
"ecosystem": "go"
},
{
"name": "github.com/bytedance/sonic",
"direct": false,
"version": "v1.15.0",
"ecosystem": "go"
},
{
"name": "github.com/bytedance/sonic/loader",
"direct": false,
"version": "v0.5.0",
"ecosystem": "go"
},
{
"name": "github.com/cenkalti/backoff/v5",
"direct": false,
"version": "v5.0.3",
"ecosystem": "go"
},
{
"name": "github.com/cespare/xxhash/v2",
"direct": false,
"version": "v2.3.0",
"ecosystem": "go"
},
{
"name": "github.com/clbanning/mxj/v2",
"direct": false,
"version": "v2.5.6",
"ecosystem": "go"
},
{
"name": "github.com/cloudwego/base64x",
"direct": false,
"version": "v0.1.6",
"ecosystem": "go"
},
{
"name": "github.com/cloudwego/gopkg",
"direct": false,
"version": "v0.1.4",
"ecosystem": "go"
},
{
"name": "github.com/cloudwego/netpoll",
"direct": false,
"version": "v0.7.2",
"ecosystem": "go"
},
{
"name": "github.com/davecgh/go-spew",
"direct": false,
"version": "v1.1.2-0.20180830191138-d8f796af33cc",
"ecosystem": "go"
},
{
"name": "github.com/dgryski/go-rendezvous",
"direct": false,
"version": "v0.0.0-20200823014737-9f7001d12a5f",
"ecosystem": "go"
},
{
"name": "github.com/fsnotify/fsnotify",
"direct": false,
"version": "v1.5.4",
"ecosystem": "go"
},
{
"name": "github.com/gabriel-vasile/mimetype",
"direct": false,
"version": "v1.4.8",
"ecosystem": "go"
},
{
"name": "github.com/go-logr/logr",
"direct": false,
"version": "v1.4.3",
"ecosystem": "go"
},
{
"name": "github.com/go-logr/stdr",
"direct": false,
"version": "v1.2.2",
"ecosystem": "go"
},
{
"name": "github.com/golang/glog",
"direct": false,
"version": "v1.2.5",
"ecosystem": "go"
},
{
"name": "github.com/golang/mock",
"direct": false,
"version": "v1.6.0",
"ecosystem": "go"
},
{
"name": "github.com/golang/protobuf",
"direct": false,
"version": "v1.5.4",
"ecosystem": "go"
},
{
"name": "github.com/grpc-ecosystem/grpc-gateway/v2",
"direct": false,
"version": "v2.28.0",
"ecosystem": "go"
},
{
"name": "github.com/hashicorp/errwrap",
"direct": false,
"version": "v1.1.0",
"ecosystem": "go"
},
{
"name": "github.com/hashicorp/go-multierror",
"direct": false,
"version": "v1.1.1",
"ecosystem": "go"
},
{
"name": "github.com/huandu/xstrings",
"direct": false,
"version": "v1.5.0",
"ecosystem": "go"
},
{
"name": "github.com/inconshreveable/mousetrap",
"direct": false,
"version": "v1.1.0",
"ecosystem": "go"
},
{
"name": "github.com/jackc/pgpassfile",
"direct": false,
"version": "v1.0.0",
"ecosystem": "go"
},
{
"name": "github.com/jackc/pgservicefile",
"direct": false,
"version": "v0.0.0-20240606120523-5a60cdf6a761",
"ecosystem": "go"
},
{
"name": "github.com/jackc/pgx/v5",
"direct": false,
"version": "v5.9.2",
"ecosystem": "go"
},
{
"name": "github.com/jackc/puddle/v2",
"direct": false,
"version": "v2.2.2",
"ecosystem": "go"
},
{
"name": "github.com/jinzhu/inflection",
"direct": false,
"version": "v1.0.0",
"ecosystem": "go"
},
{
"name": "github.com/jinzhu/now",
"direct": false,
"version": "v1.1.5",
"ecosystem": "go"
},
{
"name": "github.com/json-iterator/go",
"direct": false,
"version": "v1.1.12",
"ecosystem": "go"
},
{
"name": "github.com/klauspost/cpuid/v2",
"direct": false,
"version": "v2.2.9",
"ecosystem": "go"
},
{
"name": "github.com/leodido/go-urn",
"direct": false,
"version": "v1.4.0",
"ecosystem": "go"
},
{
"name": "github.com/masterminds/goutils",
"direct": false,
"version": "v1.1.1",
"ecosystem": "go"
},
{
"name": "github.com/masterminds/semver/v3",
"direct": false,
"version": "v3.3.0",
"ecosystem": "go"
},
{
"name": "github.com/mattn/go-colorable",
"direct": false,
"version": "v0.1.13",
"ecosystem": "go"
},
{
"name": "github.com/mattn/go-isatty",
"direct": false,
"version": "v0.0.20",
"ecosystem": "go"
},
{
"name": "github.com/mattn/go-sqlite3",
"direct": false,
"version": "v1.14.22",
"ecosystem": "go"
},
{
"name": "github.com/mitchellh/copystructure",
"direct": false,
"version": "v1.2.0",
"ecosystem": "go"
},
{
"name": "github.com/mitchellh/reflectwalk",
"direct": false,
"version": "v1.0.2",
"ecosystem": "go"
},
{
"name": "github.com/modern-go/concurrent",
"direct": false,
"version": "v0.0.0-20180306012644-bacd9c7ef1dd",
"ecosystem": "go"
},
{
"name": "github.com/modern-go/reflect2",
"direct": false,
"version": "v1.0.2",
"ecosystem": "go"
},
{
"name": "github.com/openzipkin/zipkin-go",
"direct": false,
"version": "v0.4.3",
"ecosystem": "go"
},
{
"name": "github.com/oschwald/maxminddb-golang",
"direct": false,
"version": "v1.13.0",
"ecosystem": "go"
},
{
"name": "github.com/pmezard/go-difflib",
"direct": false,
"version": "v1.0.1-0.20181226105442-5d4384ee4fb2",
"ecosystem": "go"
},
{
"name": "github.com/robfig/cron/v3",
"direct": false,
"version": "v3.0.1",
"ecosystem": "go"
},
{
"name": "github.com/shopspring/decimal",
"direct": false,
"version": "v1.4.0",
"ecosystem": "go"
},
{
"name": "github.com/smartwalle/ncrypto",
"direct": false,
"version": "v1.0.4",
"ecosystem": "go"
},
{
"name": "github.com/smartwalle/ngx",
"direct": false,
"version": "v1.0.9",
"ecosystem": "go"
},
{
"name": "github.com/smartwalle/nsign",
"direct": false,
"version": "v1.0.9",
"ecosystem": "go"
},
{
"name": "github.com/spf13/cast",
"direct": false,
"version": "v1.7.0",
"ecosystem": "go"
},
{
"name": "github.com/spf13/pflag",
"direct": false,
"version": "v1.0.5",
"ecosystem": "go"
},
{
"name": "github.com/stretchr/objx",
"direct": false,
"version": "v0.5.2",
"ecosystem": "go"
},
{
"name": "github.com/tidwall/gjson",
"direct": false,
"version": "v1.14.4",
"ecosystem": "go"
},
{
"name": "github.com/tidwall/match",
"direct": false,
"version": "v1.1.1",
"ecosystem": "go"
},
{
"name": "github.com/tidwall/pretty",
"direct": false,
"version": "v1.2.0",
"ecosystem": "go"
},
{
"name": "github.com/tjfoc/gmsm",
"direct": false,
"version": "v1.4.1",
"ecosystem": "go"
},
{
"name": "github.com/twitchyliquid64/golang-asm",
"direct": false,
"version": "v0.15.1",
"ecosystem": "go"
},
{
"name": "github.com/yuin/gopher-lua",
"direct": false,
"version": "v1.1.1",
"ecosystem": "go"
},
{
"name": "go.opentelemetry.io/auto/sdk",
"direct": false,
"version": "v1.2.1",
"ecosystem": "go"
},
{
"name": "go.opentelemetry.io/otel/exporters/otlp/otlptrace",
"direct": false,
"version": "v1.43.0",
"ecosystem": "go"
},
{
"name": "go.opentelemetry.io/otel/metric",
"direct": false,
"version": "v1.43.0",
"ecosystem": "go"
},
{
"name": "go.opentelemetry.io/proto/otlp",
"direct": false,
"version": "v1.10.0",
"ecosystem": "go"
},
{
"name": "go.uber.org/atomic",
"direct": false,
"version": "v1.7.0",
"ecosystem": "go"
},
{
"name": "go.uber.org/multierr",
"direct": false,
"version": "v1.11.0",
"ecosystem": "go"
},
{
"name": "golang.org/x/arch",
"direct": false,
"version": "v0.13.0",
"ecosystem": "go"
},
{
"name": "golang.org/x/exp",
"direct": false,
"version": "v0.0.0-20240525044651-4c93da0ed11d",
"ecosystem": "go"
},
{
"name": "golang.org/x/net",
"direct": false,
"version": "v0.55.0",
"ecosystem": "go"
},
{
"name": "golang.org/x/sync",
"direct": false,
"version": "v0.20.0",
"ecosystem": "go"
},
{
"name": "golang.org/x/sys",
"direct": false,
"version": "v0.45.0",
"ecosystem": "go"
},
{
"name": "golang.org/x/text",
"direct": false,
"version": "v0.37.0",
"ecosystem": "go"
},
{
"name": "google.golang.org/genproto/googleapis/api",
"direct": false,
"version": "v0.0.0-20260414002931-afd174a4e478",
"ecosystem": "go"
},
{
"name": "google.golang.org/genproto/googleapis/rpc",
"direct": false,
"version": "v0.0.0-20260414002931-afd174a4e478",
"ecosystem": "go"
},
{
"name": "gopkg.in/alexcesaro/quotedprintable.v3",
"direct": false,
"version": "v3.0.0-20150716171945-2caba252f4dc",
"ecosystem": "go"
},
{
"name": "gopkg.in/ini.v1",
"direct": false,
"version": "v1.67.0",
"ecosystem": "go"
}
],
"collected": true,
"truncated": false,
"total_count": 143,
"direct_count": 57,
"indirect_count": 86
}
},
"maintainership": {
"issues": {
"open_prs": 0,
"merged_prs": 57,
"open_issues": 3,
"closed_ratio": 0.975,
"closed_issues": 119,
"closed_unmerged_prs": 21
},
"bus_factor": 1,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "Ember-Moth",
"commits": 200,
"avatar_url": "https://avatars.githubusercontent.com/u/177856324?v=4"
},
{
"type": "User",
"login": "missish",
"commits": 8,
"avatar_url": "https://avatars.githubusercontent.com/u/51436036?v=4"
},
{
"type": "User",
"login": "echoowall",
"commits": 8,
"avatar_url": "https://avatars.githubusercontent.com/u/7361042?v=4"
},
{
"type": "User",
"login": "LeifDraven",
"commits": 7,
"avatar_url": "https://avatars.githubusercontent.com/u/177191628?v=4"
},
{
"type": "User",
"login": "web-ppanel",
"commits": 7,
"avatar_url": "https://avatars.githubusercontent.com/u/182197017?v=4"
},
{
"type": "User",
"login": "sky-line-1",
"commits": 6,
"avatar_url": "https://avatars.githubusercontent.com/u/218066080?v=4"
},
{
"type": "User",
"login": "hainingning",
"commits": 5,
"avatar_url": "https://avatars.githubusercontent.com/u/94955691?v=4"
},
{
"type": "User",
"login": "lyndon986",
"commits": 3,
"avatar_url": "https://avatars.githubusercontent.com/u/170910308?v=4"
},
{
"type": "User",
"login": "darwinchow",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/69086749?v=4"
},
{
"type": "User",
"login": "EUForest",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/182533708?v=4"
}
],
"contributors_sampled": 15,
"top_contributor_share": 0.797
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"develop.yaml",
"issue-check-inactive.yml",
"issue-close-require.yml",
"issue-remove-inactive.yml",
"performance.yml",
"release.yml",
"swagger.yaml",
"triage-automation.yml"
],
"has_docs_dir": true,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"go.sum"
],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": null,
"reason": "no pull request found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 0/30 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 3,
"reason": "project has 1 contributing companies or organizations -- score normalized to 3",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": 10,
"reason": "packaging workflow detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "no SAST tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": 0,
"reason": "Project has not signed or included provenance with any releases.",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 7,
"reason": "3 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "d1d81a404958a9a5e0f92f4fbddcca4762cd82d3",
"ran_at": "2026-07-24T13:48:11Z",
"aggregate_score": 3.8,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-24T13:44:07Z",
"oldest_open_prs": [],
"last_merged_pr_at": "2026-07-23T14:10:57Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 183,
"created_at": "2026-07-08T15:07:07Z",
"last_comment_at": "2026-07-15T09:03:00Z",
"last_comment_author": "x0h0i"
},
{
"number": 201,
"created_at": "2026-07-23T13:34:25Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 202,
"created_at": "2026-07-24T12:30:49Z",
"last_comment_at": null,
"last_comment_author": null
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/perfect-panel/backend",
"host": "github.com",
"name": "backend",
"owner": "perfect-panel"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 63,
"inputs": {
"security": 48,
"vitality": 88,
"community": 51,
"governance": 53,
"engineering": 72
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "excellent",
"name": "Vitality",
"value": 88,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "excellent",
"name": "Development activity",
"note": null,
"notes": [],
"value": 87,
"inputs": {
"commits_last_year": 410,
"human_commit_share": 1,
"days_since_last_push": 0,
"active_weeks_last_year": 33
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "33/52 weeks with commits",
"points": 22.8,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 33
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "410 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 410
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": null,
"notes": [],
"value": 90,
"inputs": {
"releases_count": 89,
"latest_release_tag": "v1.15.0",
"releases_from_tags": false,
"days_since_latest_release": 0,
"mean_days_between_releases": 0.2
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "89 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 89
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~0.2 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 0.2
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "maintained",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": null,
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": 0,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 0 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 0
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "moderate",
"name": "Community & Adoption",
"value": 51,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "moderate",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 51,
"inputs": {
"forks": 91,
"stars": 137,
"watchers": 2,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "137 stars",
"points": 34.6,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 137
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "91 forks",
"points": 16.3,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 91
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "2 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 2
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (GPL-3.0)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "GPL-3.0"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 53,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "at_risk",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 30,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 15,
"top_contributor_share": 0.797
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 80% of commits",
"points": 4.6,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 80
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "15 contributors",
"points": 13.5,
"status": "met",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 15
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 3,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "good",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 74,
"inputs": {
"merged_prs": 57,
"open_issues": 3,
"closed_issues": 119,
"issue_closed_ratio": 0.975,
"closed_unmerged_prs": 21
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "98% of issues closed",
"points": 45.6,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 98
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "57/78 decided PRs merged",
"points": 28,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 57,
"decided": 78
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 60,
"inputs": {
"followers": 203,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "perfect-panel",
"public_repos": 21,
"account_age_days": 679
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "organization-owned",
"points": 30,
"status": "met",
"details": [
{
"code": "owner_organization",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "203 followers of perfect-panel",
"points": 16.6,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 203,
"login": "perfect-panel"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "21 public repos, account ~1 yr old",
"points": 13.5,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 21
}
},
{
"code": "account_age_years",
"params": {
"years": 1
}
}
],
"max_points": 25
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "good",
"name": "Engineering Quality",
"value": 72,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "moderate",
"name": "Engineering practices",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_ci_tests"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 60,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "8 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 8
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "excellent",
"name": "Documentation",
"note": null,
"notes": [],
"value": 90,
"inputs": {
"topics": [],
"has_wiki": true,
"homepage": "https://ppanel.dev",
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": "https://ppanel.dev",
"points": 15,
"status": "met",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "at_risk",
"name": "Security",
"value": 48,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): CI-Tests. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"ci_tests"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 38,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 17,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 1,
"scorecard_aggregate": 3.8
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 0.8,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "no SAST tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "3 existing vulnerabilities detected",
"points": 5.2,
"status": "partial",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "dependency_advisories",
"band": "excellent",
"name": "Dependency advisories",
"note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories. Remaining weights renormalized. Matched 143 resolved dependencies against OSV. This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"indirect_dependencies_free_of_known_advisories"
]
}
},
{
"code": "weights_renormalized",
"params": {}
},
{
"code": "advisories_scope_repository",
"params": {
"assessed": 143
}
},
{
"code": "advisories_repo_graph_caveat",
"params": {}
},
{
"code": "advisories_reachability",
"params": {}
}
],
"value": 89,
"inputs": {
"source": "osv",
"advisories": 3,
"affected_packages": 3,
"assessed_packages": 143,
"unassessed_packages": 0,
"affected_by_severity": "unknown 3",
"direct_affected_packages": 1
},
"components": [
{
"key": "direct_dependencies_free_of_known_advisories",
"name": "Direct dependencies free of known advisories",
"detail": "1 affected: golang.org/x/crypto v0.52.0 (unknown)",
"points": 26.6,
"status": "partial",
"details": [
{
"code": "advisories_affected",
"params": {
"count": 1,
"packages": "golang.org/x/crypto v0.52.0 (unknown)"
}
}
],
"max_points": 35
},
{
"key": "indirect_dependencies_free_of_known_advisories",
"name": "Indirect dependencies free of known advisories",
"detail": "transitive set not separable from development and test dependencies in this scope",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_scope_not_separable",
"params": {}
}
],
"max_points": 25
},
{
"key": "no_advisories_left_outstanding",
"name": "No advisories left outstanding",
"detail": "no advisory has been public longer than 90 days",
"points": 40,
"status": "met",
"details": [
{
"code": "advisories_none_stale",
"params": {
"days": 90
}
}
],
"max_points": 40
}
]
},
{
"key": "malicious_dependencies",
"band": "excellent",
"name": "Malicious dependencies",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"source": "osv",
"meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
"packages": [],
"red_flag": false,
"assessed_packages": 143,
"malicious_packages": 0,
"direct_malicious_packages": 0,
"withdrawn_malicious_packages": 0,
"installable_malicious_packages": 0
},
"components": [
{
"key": "no_dependency_reported_as_a_malicious_package",
"name": "No dependency reported as a malicious package",
"detail": "no dependency is reported as a malicious package",
"points": 100,
"status": "met",
"details": [
{
"code": "no_malicious_dependencies",
"params": {}
}
],
"max_points": 100
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 3
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "moderate",
"name": "AI Readiness",
"value": 57,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "at_risk",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.99,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "no CLAUDE.md / AGENTS.md / editor rules",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_instructions",
"params": {}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "99 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 99,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "moderate",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 61,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"go.sum"
],
"has_dockerfile": true,
"typed_language": true,
"bootstrap_files": [
"Makefile"
],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [],
"agent_commit_share": 0,
"toolchain_manifests": [
"go.mod"
],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "Makefile",
"points": 18,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Makefile"
}
}
],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "Go (statically typed)",
"points": 11,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Go"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "Dockerfile, lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Dockerfile, lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "no agent-authored commits among the last 100",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_authored_commits",
"params": {
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"primary_language": "Go",
"largest_source_bytes": 68597,
"source_files_sampled": 1067,
"oversized_source_files": 1
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Go (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Go"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "1/1067 source files over 60KB",
"points": 54.9,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 1067,
"oversized": 1
}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "at_risk",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"example_dirs": [],
"has_mcp_signal": false,
"api_schema_files": [
".github/workflows/swagger.yaml",
"api/server/v1/server.proto"
]
},
"components": [
{
"key": "api_schema_openapi_graphql_proto",
"name": "API schema (OpenAPI/GraphQL/proto)",
"detail": ".github/workflows/swagger.yaml, api/server/v1/server.proto",
"points": 40,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": ".github/workflows/swagger.yaml, api/server/v1/server.proto"
}
}
],
"max_points": 40
},
{
"key": "mcp_server",
"name": "MCP server",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "runnable_examples",
"name": "Runnable examples",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 40
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"go package 'github.com/perfect-panel/server' points at a different repository (https://github.com/perfect-panel/server); excluded from ecosystem scoring"
],
"report_type": "repository",
"generated_at": "2026-07-24T13:48:24.402240Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/p/perfect-panel/backend.svg",
"full_name": "perfect-panel/backend",
"license_state": "standard",
"license_spdx": "GPL-3.0"
}