-
Notifications
You must be signed in to change notification settings - Fork 0
docs(agents): ADR status fixes, price correction, gen-today cadence fix #3475
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
85f1159
71566da
f78b5ba
3785a50
3a89715
ca7ab3f
e44da3a
923350e
4e9af0b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,7 @@ | |
| - **Supersedes:** — | ||
| - **Related:** | ||
| - [`docs/04-governance/adr/0001-monetization-architecture.md`](./0001-monetization-architecture.md) — ADR-1.1 (Stripe primary), ADR-1.8 (webhook event-id retention), ADR-1.11 (cancel-at-period-end). | ||
| - [`docs/01-product/launch/business/01-monetization-and-pricing.md`](../../01-product/launch/business/01-monetization-and-pricing.md) — тіри і ціни (Pro ₴99/міс, ₴799/рік). | ||
| - [`docs/01-product/launch/business/01-monetization-and-pricing.md`](../../01-product/launch/business/01-monetization-and-pricing.md) — тіри і ціни (Pro $7/міс, $49/рік). <!-- price updated 2026-06-09: ₴99/міс → $7/міс per ADR-0051 --> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Switch inline HTML notes to the required AI marker format. The added As per coding guidelines, “ Also applies to: 25-27, 305-305 🧰 Tools🪛 LanguageTool[style] ~10-~10: Після голосної зі звуком і/и варто писати й або та: тіри «й» ціни, тіри «та» ціни (EUPHONY_CONJ_I_Y) 🤖 Prompt for AI AgentsSource: Coding guidelines Ukrainian euphony typo in the updated phrase. “тіри і ціни” should be adjusted to the euphonically correct conjunction form. 🧰 Tools🪛 LanguageTool[style] ~10-~10: Після голосної зі звуком і/и варто писати й або та: тіри «й» ціни, тіри «та» ціни (EUPHONY_CONJ_I_Y) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| - [`docs/01-product/launch/business/06-monetization-architecture.md`](../../01-product/launch/business/06-monetization-architecture.md) — risk register #8 («нічого про refund / proration»). | ||
|
|
||
| --- | ||
|
|
@@ -22,8 +22,9 @@ ADR-0001 явно винісь refund / dispute flow в окремий ADR (ди | |
| app — Pro у юзера лишається активним, навіть якщо платіж вже відкликано; (б) | ||
| без явної політики повернень ми порушуємо вимоги Stripe Standard Acceptable | ||
| Use Policy (refund policy має бути доступна юзеру **до** оплати); (в) при ціні | ||
| Pro ₴99/міс (~$2.30) комісія Stripe за один dispute (€15) повністю з'їдає | ||
| 6 місяців оплати — політика чисто-grace для disputes економічно нестійка. | ||
| Pro $7/міс <!-- price updated 2026-06-09: ₴99/міс → $7/міс per ADR-0051 --> | ||
| комісія Stripe за один dispute (€15) повністю з'їдає кілька місяців оплати — | ||
| політика чисто-grace для disputes економічно нестійка. | ||
|
|
||
| | Сценарій | Тригер | Дія | | ||
| | ------------------------------ | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | ||
|
|
@@ -300,3 +301,5 @@ accepted. | |
| balance — можна замість refund-у нарахувати credit на наступний цикл. | ||
| Менше тертя для returning-юзерів. Reopen якщо побачимо ≥30% refund-ів | ||
| "хочу скасувати, але повернуся" (типовий churn-recovery кейс). | ||
|
|
||
| <!-- price updated 2026-06-09: ₴99/міс → $7/міс per ADR-0051 --> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,7 +31,7 @@ function arbitraryLocalDate(): Date { | |
| const year = 1970 + Math.floor(rng() * 130); | ||
| const month = Math.floor(rng() * 12); // 0..11 | ||
| const day = 1 + Math.floor(rng() * 28); // 1..28, always valid | ||
| const hour = Math.floor(rng() * 24); | ||
| const hour = Math.floor(rng() * 21); // 0..20: UTC 21–23 crosses to next Kyiv day | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make test data timezone-explicit (UTC) to avoid env-dependent Kyiv-day flakes. These changes still use local-time Suggested fix function arbitraryLocalDate(): Date {
const year = 1970 + Math.floor(rng() * 130);
const month = Math.floor(rng() * 12); // 0..11
const day = 1 + Math.floor(rng() * 28); // 1..28, always valid
- const hour = Math.floor(rng() * 21); // 0..20: UTC 21–23 crosses to next Kyiv day
+ const hour = Math.floor(rng() * 21); // 0..20 UTC: avoids Kyiv next-day rollover
const minute = Math.floor(rng() * 60);
- return new Date(year, month, day, hour, minute);
+ return new Date(Date.UTC(year, month, day, hour, minute));
}
...
- const earlyMorning = new Date(
- base.getFullYear(),
- base.getMonth(),
- base.getDate(),
+ const earlyMorning = new Date(Date.UTC(
+ base.getUTCFullYear(),
+ base.getUTCMonth(),
+ base.getUTCDate(),
6,
0,
0,
- );
- const lateEvening = new Date(
- base.getFullYear(),
- base.getMonth(),
- base.getDate(),
+ ));
+ const lateEvening = new Date(Date.UTC(
+ base.getUTCFullYear(),
+ base.getUTCMonth(),
+ base.getUTCDate(),
20,
0,
0,
- );
+ ));Also applies to: 67-69, 72-88 🤖 Prompt for AI AgentsSource: Coding guidelines |
||
| const minute = Math.floor(rng() * 60); | ||
| return new Date(year, month, day, hour, minute); | ||
| } | ||
|
|
@@ -64,25 +64,28 @@ describe("shared/utils/date – toLocalISODate property", () => { | |
| }); | ||
|
|
||
| it("is time-of-day invariant: only the calendar day matters", () => { | ||
| // Use 06:00 and 20:00 UTC — both safely within the same Kyiv calendar day | ||
| // regardless of DST offset (UTC+2 winter: 08:00/22:00; UTC+3 summer: 09:00/23:00). | ||
| // UTC 21–23 would cross Kyiv midnight, so we avoid those hours here. | ||
| for (let i = 0; i < NUM_RUNS; i++) { | ||
| const base = arbitraryLocalDate(); | ||
| const midnight = new Date( | ||
| const earlyMorning = new Date( | ||
| base.getFullYear(), | ||
| base.getMonth(), | ||
| base.getDate(), | ||
| 0, | ||
| 6, | ||
| 0, | ||
| 0, | ||
| ); | ||
| const lateNight = new Date( | ||
| const lateEvening = new Date( | ||
| base.getFullYear(), | ||
| base.getMonth(), | ||
| base.getDate(), | ||
| 23, | ||
| 59, | ||
| 59, | ||
| 20, | ||
| 0, | ||
| 0, | ||
| ); | ||
| expect(toLocalISODate(lateNight)).toBe(toLocalISODate(midnight)); | ||
| expect(toLocalISODate(lateEvening)).toBe(toLocalISODate(earlyMorning)); | ||
| } | ||
| }); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the canonical auto-generated marker prefix.
This file is auto-generated, but the header does not start with the required
<!-- AUTO-GENERATED -->marker form for docs generators/checks.As per coding guidelines, “Auto-generated documentation must start with
<!-- AUTO-GENERATED -->marker per Hard Rule#25”.🤖 Prompt for AI Agents
Source: Coding guidelines