Repository navigation
feat(ui): add the "new this month" card to the sharing page - #175
Merged
Merged
Conversation
The sharing page's stat row had three cards where the prototype has four:
the fourth ("本月新增") was missing because GET /api/sharings never returned
a row's listing time, so the client had nothing to count.
- sharing_row() now returns `created_at` (UTC ISO via dao::utc_iso, the same
convention as api_keys.created_at). sharing_row() reads its columns
POSITIONALLY, so both of its call sites (the list SELECT and the
single-row PATCH SELECT) gain the column in this one commit, appended at
the end; a one-sided change would silently shift every field.
- renderSharing() renders the fourth card. The month key is derived from the
UTC timestamp (utcMonth -> YYYY-MM), matching the SQL-side
strftime('%Y-%m', ...) every other aggregate in this repo uses; using the
local month would disagree with the rest of the page for the first eight
hours of each month in UTC+8. Rows without a created_at are not counted
(under-report rather than mis-report).
- The subtitle deliberately does not copy the prototype, which hardcodes the
model name "deepseek-v4-flash" on a card that may aggregate several models
(the prototype's own table renders multiple rows): a single listing shows
its model, several show a generic label, none shows an empty-state label.
- New bilingual keys share.stats.newthis{,.sub,.none}; the i18n_pack gate's
maintained counts move 783 -> 786 keys and 531 -> 535 call sites
(426 -> 429 distinct).
- ui/README.md documents the convention, and corrects a stale line claiming
the sharing list has a 上架时间 column (it never had one; no column added
here either, so the table's 8-column colspan stays consistent).
Tests: sharing::tests::created_at_is_exposed_and_utc_serialized asserts both
SELECTs and the UTC serialization using a `2026-08-31 17:30:00` timestamp,
which is August in UTC but September locally (UTC+8) - so a local-time
regression is distinguishable rather than self-confirming.
Co-authored-by: argszero <argszero@argszerodeMac-mini.local>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The sharing page's stat row showed three cards where the prototype shows four — the fourth, 「本月新增」(new this month), was missing. The reason was on the backend:
GET /api/sharingsnever returned a row's listing time, so the client had nothing to count. This PR exposes that field and renders the card.keys.created_athas existed since the schema's first commit, so no migration is involved; only the SELECT and the response were missing it.Related Issue
Changes
sharing_row()(src/routes/sharing.rs) now returnscreated_at, serialized with the existingdao::utc_iso— same convention asapi_keys.created_at.sharing_row()reads its columns positionally (r.get(0..12)), so its two call sites — the listSELECTand the single-rowPATCHSELECT— both gain the column in this one commit, appended at the end. A one-sided change would silently shift every field without erroring.renderSharing()(ui/js/app.js) renders the fourth stat card, counting rows whose listing time falls in the current month.utcMonth→YYYY-MM), matching the SQL-sidestrftime('%Y-%m', …)that every other aggregate in this repo uses (ops.rs,wallet.rs,admin.rs,org.rs). Using the local month would disagree with the rest of the page for the first eight hours of each month in UTC+8. Rows without acreated_atare not counted — under-report rather than mis-report.deepseek-v4-flashon a card that may aggregate several models (the prototype's own table renders multiple rows). A single listing shows its model name, several show a generic label, none shows an empty-state label.share.stats.newthis{,.sub,.none}; thei18n_packgate's maintained counts move 783 → 786 keys and 531 → 535 call sites (426 → 429 distinct).ui/README.mddocuments the convention, and corrects a stale line that claimed the sharing list has a 上架时间 column — it never had one (neither the prototype nor the implementation), and no column is added here, so the table's 8-columncolspanstays consistent.config/config.example.tomlchange — this touches no configuration or data structure.keys.created_atexisted already.Tests
cargo test全部通过 — 164 passed / 0 failed (163 before; +1 new).cargo fmt --check通过cargo clippy --all-targets -- -D warnings通过New test
sharing::tests::created_at_is_exposed_and_utc_serializedasserts:SELECTs carry the column — theGET /api/sharingslist and thePATCH /api/sharings/:idresponse are both asserted (they read from two separate column lists, which is the shape that fails silently);2026-08-31 17:30:00, which is August in UTC but already September in UTC+8, so a local-time regression is distinguishable rather than self-confirming.Both assertions were proven to have teeth before landing, by injecting the defect and watching them fail (then restoring the file and verifying its md5):
created_atfrom only thePATCHSELECT →Invalid column index: 12on the PATCH path, while theGETpath still passed (exactly the one-sided-drift failure mode);utc_iso→left: "2026-08-31 17:30:00"vsright: "2026-08-31T17:30:00Z".An A/B run of the real
renderSharing()against the real language packs (before tree fromgit show HEAD:ui/js/app.js, same generator and same stub data for both legs) went 15/15: BEFORE 3 cards and no 「本月新增」 label → AFTER 4 cards; count3 个for 3 in-month rows out of 4; subtitle多个模型; single in-month row → subtitle = that row's model (glm-5.2); zero in-month rows →0 个+ 「本月还没有上架」; a2026-09-30T23:30:00Zrow still counts in September. It also asserts the prototype's hardcoded literals (1,deepseek-v4-flash) never appear.Checklist