vyvoj-dash

Tasky

62 tasků

Kanban board tasků — filtr dle priority, labelu nebo runu.

Priorita:
Run: n nový 1-5 přesun
Backlog
0
Prázdné
To Do
0
Prázdné
In Progress
0
Prázdné
Hotovo
62
Testy pro nové edge cases

Nový test v package.spec ověřuje že non-JSON upstream odpověď produkuje 502 s error.contains('malformed').

Střední
Ošetření chyby JSON.parse v metadata fallbacku

Pokud npmjs.org vrátí 200 ale non-JSON tělo (HTML chybová stránka při výpadku), worker padal na náhodné 500. Teď try/catch okolo JSON.parse vrací strukturované 502 Bad Gateway.

Střední
Ošetření chyb při zápisu tarballu do R2 cache

Zápis tarballu do R2 cache (ctx.waitUntil) mohl selhat tiše s unhandled rejection. Přidán .catch s logováním package+key, klient dostane stream bez ohledu na cache.

Střední
Logika mazání starých fallback tarballů z R2

Fallback tarbally se v R2 hromadily bez TTL — pro popular balíčky to mohlo růst do GB ročně. Daily scheduled volá funkci, která projde R2 list s customMetadata, filtruje source=fallback + uploaded > 90 dní a batch maže.

Střední
Cron trigger v Wrangler config

wrangler.jsonc triggers.crons '0 3 * * *' — denně ve 3:00 UTC. Cron registrace ověřena přes CF API workers/scripts/.../schedules.

Střední
Test scheduled handleru

Vitest 3 testy: recent fallback survive, own packages never deleted, no side effects. Backdate uploaded netestováno (R2 binding read-only), jen invariants pro in-TTL chování.

Střední
Custom worker entry s scheduled handlerem

Astro 6 adapter generoval jen fetch handler, scheduled cron nešel jednoduše přidat. Vytvořen custom worker entry kombinující Astro handle (přes @astrojs/cloudflare/handler) a scheduled handler.

Střední
Test non-scoped balíčku přes plný proxy

Run 012 nepokrýval success path proxy stahování. Test ověří round-trip: metadata fetch z fallbacku má dist.tarball přepsaný na vlastní host, druhý request tarball stream vrátí mock body byte-by-byte.

Střední
Test scoped balíčku přes plný proxy

Scoped balíčky byly bug-prone (regex transformace + scope strip). Test ověří úplný řetězec: URL-encoded /@types%2Fnode metadata → rewrite na double-scope, navazující tarball download projde 5-seg scoped route a strip-scope upstream fetch.

Střední
Test cache hit při druhém stažení

Po prvním cache miss by druhý fetch měl jít z R2 bez upstream callu. Test pre-populuje BUCKET (eliminuje waitUntil timing flakiness) a ověří, že read s cache-hit metadatami vrátí body bez jakéhokoli mocku k upstream.

Střední
Hono router pro fallback tarball

Service změnila kontrakt z R2ObjectBody na ReadableStream — router teď wrapuje do Response s Content-Type: application/gzip a předává c.executionCtx pro async cache write.

Střední
Přepis URL tarballů v metadata fallbacku

Fallback metadata vracela URL na npmjs.org — v plném proxy režimu klient pak chodil mimo Repoflare. Teď JSON.parse + per-version dist.tarball rewrite na vlastní host; scoped balíčky se transformují na Repoflare double-scope formát, aby matchly existující 5-segment scoped route.

Střední
Návod dual-mode (scope-first + full-proxy)

Návod byl psaný jen pro plný proxy režim, scope-first nebyl vysvětlen. Sekce 2 přepsána na scope-first jako doporučené, sekce 5 přejmenována na 'Plný proxy režim' pro lockdown setupy s anchor odkazem mezi nimi.

Střední
Stream proxy a R2 cache pro tarbally

Tarbally veřejných balíčků se stahovaly přímo z npmjs.org → v lockdown sítích nešly a R2 cache se neplnila. Service teď na R2 miss fetchne upstream, tee() split stream do cache i klientovi, ctx.waitUntil schová R2 put na pozadí.

Střední
Sjednocení textů u prázdných seznamů

Texty u prázdných seznamů byly nekonzistentní ('Žádné tokeny.' vs jiné varianty). Sjednoceno na vzor 'Zatím tu nejsou žádné X.' u tokenů i balíčků.

Střední
Vlastní 404 stránka

Astro default 404 vrací plain text. Přidána vlastní stránka 404.astro s BaseLayout, headerem a CTA tlačítky na úvod a dashboard.

Střední
Ošetření chyby kopírování do schránky

Při zamítnutí oprávnění na clipboard padalo unhandled promise. Tlačítka pro kopírování teď mají tristate (idle/copied/failed) s 2s flashí 'Kopírování selhalo'.

Střední
Vylepšení chybové hlášky u vytváření tokenu

Chybová hláška u tokenu byla jen tichý červený text. Nyní má výraznější border, dismiss tlačítko a aria-describedby, takže screen reader chybu spojí s polem názvu.

Střední
Přístupnost — focus, ARIA, ikony

Klávesnicová a screen-reader přístupnost. Šipky '←' v back-link odkazech obaleny aria-hidden, fokus-visible ring doplněn na plain <a> odkazy, search input dostal aria-label a počet je aria-live.

Střední
Middleware: + /docs do allowlist

Middleware isAstro allowlist neměl /docs. Rozšířen o pathname === '/docs' — request projde Access verify a renderuje docs.astro.

Střední
Stránka docs.astro s návodem

Návštěvníci neměli kde najít jak registry používat. Vytvořen src/pages/docs.astro: 6 sekcí v CS (vygenerovat token z dashboardu, nastavit .npmrc per-host i per-scope, publish, install s npm.org fallback, scoped balíčky, troubleshoot 401/403/409).

Střední
Link na /docs z homepage

Homepage měla 3 tlačítka (Dashboard, API dokumentace, GitHub) — bez návodu. Přidán Návod button mezi Dashboard a API dokumentace, variant=outline (secondary CTA).

Střední
CF Access app: + /docs destination

Access app chránila jen / a /dashboard*. /docs by bez Access destination obešel ochranu (Astro middleware sice gate-uje, ale CF Access by header neposlal). Přidán třetí destination 'npm.vyvoj.dev/docs' (exact match) do existing Access app via API.

Střední
Middleware routing pro Astro root

Catch-all middleware z Run 002 delegoval všechny non-/dashboard requesty na Hono. Pro novou homepage / je potřeba povolit Astro render. Přidána explicit kontrola isAstroRoot — / projde na next() (Astro), zbytek non-/dashboard dál na Hono (NPM protokol).

Střední
Homepage index.astro s landing copy

https://npm.vyvoj.dev/ vracelo Hono 404 — návštěvník netušil co je to za službu. Vytvořen src/pages/index.astro s minimal landing: heading, 2 odstavce popisu (D1+R2+CF Access+bearer tokeny, jak nastavit .npmrc), 3 Buttons (Otevřít dashboard primary, API dokumentace outline, GitHub ghost external s rel=noopener).

Střední
Install shadcn Input/Select/Card/Alert

Run 003 nainstaloval jen Button. Run 005-007 napsaly komponenty s plain HTML inputy/selecty/error bloky — proti shadcn rule 'always use components'. Doinstalován Input, Select, Card, Alert (+ Separator transitively) přes shadcn CLI. Z select-content.svelte odstraněn defaultní shadow-md (skill no-shadow rule).

Střední
CreateTokenForm refactor

CreateTokenForm měl plain input pro name, plain select pro scope, custom red text pro error, custom green border pro success token reveal — nekonzistentní s design systemem. Refactorováno: Input pro name, Select.Root/Trigger/Content/Item pro scope (s triggerLabel $derived), Alert variant=destructive pro error, Alert default pro success s code+copy uvnitř Description.

Střední
PackageSearch refactor

PackageSearch měl plain <input type=search> s ručně napsanými border classes. Nahrazeno za <Input type=search class='max-w-md'> — méně klutterového kódu, konzistentní s ostatními formuláři.

Střední
Tokens list delete button

Delete button v tokens listu byl plain <button> s ručně napsaným destructive border + hover bg. Nahrazeno za <Button variant=destructive size=sm>. Astro renderuje SSR-only (žádný client:* directive), zero JS shipped pro tento widget — submit je native form behavior.

Střední
PackageSearch Svelte island

List balíčků se nedal prohledávat — při růstu počtu nepoužitelný. Vytvořen PackageSearch.svelte: Svelte 5 island s runes ($state pro query, $derived pro filtered list), case-insensitive substring match. Empty state rozlišuje 'no packages' vs 'no match for query'.

Střední
InstallSnippet Svelte island

Detail page nezobrazila install command — user musel hádat package name pro npm install. Vytvořen InstallSnippet.svelte: code block s 'npm install <name>' + Copy button (navigator.clipboard) s 2s 'Zkopírováno' flash, stejný pattern jako CreateTokenForm.

Střední
Index page refactor s islandem

Inline list rendering v index.astro znemožnoval interaktivní filter. Refactor: list přesunut do PackageSearch islandu (mount client:load, packages prop), SSR fetch zůstává v frontmatter. Index.astro je teď tenký shell.

Střední
Detail page mount install snippet

Detail page chyběl install snippet. Mount InstallSnippet islandu mezi description a README sekci s pkg.name jako prop, client:load pro interaktivitu copy buttonu.

Střední
Tokens list stránka

Pod /dashboard/tokens neexistovala žádná stránka. Vytvořen tokens/index.astro: SSR fetch tokenů, masked display (jen xxxx…yyyy, plaintext nikdy v listu), scope summary, formátované createdAt, delete form per řádek + mount Svelte create islandu nahoře.

Střední
Svelte 5 island na create form

Form pro create token potřebuje JS pro one-shot reveal plaintext tokenu (no-JS fallback by chtěl session storage flash). CreateTokenForm.svelte: Svelte 5 island s runes ( pro inputs/loading/error/copied, pro canSubmit), fetch POST → success render token + Copy button (navigator.clipboard) s 2s flash 'Zkopírováno'.

Střední
Helper listTokens + masking

Tokens stránky neměly query helper, pattern stejný jako u packages. Přidán listTokens v dashboard-queries (findMany ordered desc by createdAt) + samostatný mask-token util pro UI display ve formátu xxxx…yyyy bez plaintextu.

Střední
Create token endpoint

Bez Astro endpointu by Svelte island neměl kam fetchnout. Hono /-/npm/v1/tokens potřebuje bearer token (assertTokenAccess) — CF Access user ho nemá. Vytvořen create.ts: POST endpoint pod /dashboard/tokens/create (uvnitř middleware gate), zod validace + delegace na tokenService.createToken, vrací 201 s plaintext tokenem.

Střední
Delete token endpoint

Form delete potřeboval endpoint pod /dashboard/* (NE /api/*) jinak middleware skipne a Hono catch-all vrátí 404. Vytvořen [token]/delete.ts: POST handler, deleteToken + 303 redirect zpět na list. CF Access JWT funguje jako de facto CSRF token (cross-origin requesty bez něj dostanou 403).

Střední
Detail stránka balíčku s README

Detail page chyběl celý. Vytvořen [...name].astro (rest param kvůli scoped balíčkům @scope/pkg), fetch package + latest release, render README přes renderMarkdown. 404 pokud balíček neexistuje, fallback hláška pokud manifest nemá readme field.

Střední
Auth gate util require-user

Dev escape hatch v middleware nechá Astro.locals.user = null bez Access headeru. Bez gate by neautorizovaný request prošel na dashboard. Přidán shared util require-user, který vrací Response 403 nebo AccessUser — explicit return je idiomatic v Astro page frontmatter (oproti throw).

Střední
Drizzle query helpers pro dashboard

Dashboard stránky neměly query helpery, raw SQL na page by zaplevelilo frontmatter. Přidán dashboard-queries.ts: listPackages (findMany ordered desc) + getPackageWithLatestRelease (2 queries — package, pak release dle distTags.latest). Relational with-filter nešel kvůli závislosti na parent column.

Střední
Markdown rendering bez raw HTML

marked v18 neescapuje raw HTML ani nesanitizuje URL schémata — README publisher může injectnout <script> nebo [link](javascript:...). Přidán render-markdown.ts: Marked instance s renderer.html escape + allowlist URL schemes (http/https/mailto/relative) v link/image renderer.

Střední
Index stránka s listem balíčků

Pod /dashboard byl prázdný placeholder z Run 003. Index page nyní SSR fetchuje balíčky přes listPackages, zobrazí name + latest version + cs-CZ formátované updated_at, link na detail. Empty state pro 0 balíčků.

Střední
Astro middleware ochrana /dashboard/*

Astro middleware měl jen Hono delegaci a /dashboard/* puštěné dál veřejně. Přidána větev: pro /dashboard* ověří Access JWT, jinak delegate na Hono beze změny. NPM protokol nezměněn.

Střední
JWT verify pomocí jose a Access JWKS

JWT verify extracted do samostatného lib/access-jwt.ts. Module-level JWKS singleton (createRemoteJWKSet) sdílený přes requesty, jwtVerify s issuer + audience, payload.email uložen do Astro.locals.user.

Střední
Env vars TEAM_DOMAIN a POLICY_AUD

TEAM_DOMAIN a POLICY_AUD přidány do vars v wrangler.jsonc s empty defaults — produkce doplní podle access-setup.md. Wrangler types regenerated, env.* je type-safe.

Střední
Typování App.Locals.user

App.Locals neměl typ pro přihlášeného uživatele. Nový src/env.d.ts augmentuje App.Locals o user: AccessUser | null, takže pages pod /dashboard/* můžou číst locals.user.email type-safe.

Střední
Návod na setup CF Access

Žádný návod, jak Access nakonfigurovat. Nový docs/access-setup.md popisuje Self-Hosted Application + Policy + zkopírování AUD tagu, dev escape hatch a troubleshooting.

Střední
shadcn-svelte init s tokens

shadcn-svelte CLI v1.2.7 vyžaduje interaktivní preset selection, neslo skriptovat. Manuálně vytvořeny components.json + src/lib/utils.ts s cn helperem + src/styles/global.css s neutral oklch tokens. Outcome ekvivalentní.

Střední
BaseLayout a refactor dashboard pages

Dashboard byl bare HTML bez stylingu. Vytvořen src/layouts/BaseLayout.astro (slot + global.css import + viewport meta), dashboard/index.astro ho používá s Tailwind container utilities.

Střední
Button island na hello-world stránce

Plán chtěl ověřit Svelte hydration na CF Workers. pnpm dlx shadcn-svelte add button vygeneroval Button komponentu, dashboard ji ukazuje 2× — client:load (Svelte island, hydratovaný) a outline (SSR-only). Bonus: check-types přepnut z tsc na astro check kvůli Svelte type re-exports.

Střední
Astro Svelte + Tailwind v configu

astro.config.mjs měl jen adapter, web UI nemělo žádný styling. Přidán svelte() integration + @tailwindcss/vite plugin + $lib alias přes vite.resolve. Tailwind classes a Svelte 5 hydration teď fungují v .astro souborech.

Střední
Catch-all endpoint pro npm protokol

Původně catch-all endpoint v src/pages/[...npm].ts vyhodil 404 pro /_ui/, protože Astro routing prioritizuje endpoint nad page. Přepsáno na src/middleware.ts který volá next() pro /dashboard/* a app.fetch() pro vše ostatní — žádný preempt.

Střední
Přepnutí Worker entry na Astro

wrangler.jsonc: main na @astrojs/cloudflare/entrypoints/server (Astro 6 v13 unified entry), přidán account_id, custom_domain route na npm.vyvoj.dev, kv/r2/d1 bindings s reálnými ID. Worker name přejmenován na npm-vyvoj-dev.

Střední
Oprava package.json a vitest configu

vitest.config.ts měl stale wrangler.toml path a src/index.ts main z Run 001. Fix na wrangler.jsonc + nový hono-app.ts main. package.json: dev na astro dev, check-types doplněn o astro sync (Locals types). Bonus: turbo/biome/knip/sherif odstraněny.

Střední
Smoke test buildu a integration testů

Lokální astro build + vitest run prošly (55/55). Wrangler deploy --dry-run čistý. Po deploy do produkce smoke test přes curl: /dashboard/ → Astro hello-world 200, /_/docs → Scalar 200, /<package> → npm proxy 200, /-/npm/v1/tokens admin auth 200.

Střední
Přesun Hono entry do lib

Hono app byl přímo v src/index.ts a sloužil jako Worker entry. Přesun do src/lib/hono-app.ts s dual exportem (named app + default app) — named pro Astro middleware delegaci, default kvůli vitest pool worker main.

Střední
Přejmenování apps/api na apps/worker

git mv apps/api → apps/worker, package name @npflared/api → @npflared/worker. biome.json path update. Workspace glob apps/* nepotřeboval změnu.

Střední
Převod wrangler.toml na wrangler.jsonc

wrangler.toml → wrangler.jsonc se referencí, observability:enabled, compatibility_date 2026-05-10. Bindings (D1, R2, vars) zachovány s původními placeholder hodnotami.

Střední
Instalace Astro 6 + Cloudflare adapteru

pnpm add astro 6.3, @astrojs/cloudflare 13.5, @astrojs/svelte 8.1, svelte 5.55, jose 6.2, marked 18.0. Wrangler bumped 4.58 → 4.90 protože adapter peer dep požaduje ^4.83.

Střední
Astro config + minimální stránka

astro.config.mjs minimální (jen adapter cloudflare()), svelte() zatím vypnutá komentem - aktivuje Run 003. Hello-world stránka pod /_ui/ namespace aby budoucí catch-all na rootu nekolidovala s npm protokolem.

Střední
Ověření že astro build projde

pnpm astro build prošel s 0 errors. Build vyprodukoval dist/client + dist/server (Astro 6 nová struktura, ne stará dist/_worker.js). Acceptance kritérium runu splněno.

Střední
Zrušeno
0
Prázdné
Vráceno
0
Prázdné