Skip to content

feat: hostdoc insight <code> — CloudFront visit stats (#43, cloudfront slice) - #53

Open
jkas2016 wants to merge 13 commits into
mainfrom
feat/43-cloudfront-insight
Open

feat: hostdoc insight <code> — CloudFront visit stats (#43, cloudfront slice)#53
jkas2016 wants to merge 13 commits into
mainfrom
feat/43-cloudfront-insight

Conversation

@jkas2016

Copy link
Copy Markdown
Owner

Summary

Adds hostdoc insight <code> — per-document page-view hits + approximate unique visitors for cloudfront-mode sites, read from CloudFront standard-logging (v2) access logs provisioned in the user's own AWS. This is the cloudfront vertical slice of #43; s3-website and self-hosted are deferred to their own future slices.

No HTML is modified (no JS beacon), no standing server/endpoint — logs live in the user's S3 and are parsed CLI-side.

Design

Spec: docs/superpowers/specs/2026-07-11-cloudfront-insight-design.md · Plan: docs/superpowers/plans/2026-07-11-cloudfront-insight.md

  • Logging = standard logging v2 (CloudWatch vended-logs delivery), not v1 legacy. Rationale: v1 legacy requires S3 ACLs on the log bucket, which fights hostdoc's hardened private-OAC bucket model ([Enhancement] Terraform infra 하드닝 (route53·IAM·validation·description) #20); v2 is bucket-policy based (ACL-free) and supports field selection (log only the minimal set) + partitioning.
  • Dedicated private log bucket (separate from content), 30-day S3 lifecycle expiry, delivery via delivery.logs.amazonaws.com bucket policy. Partitioned {DistributionId}/{yyyy}/{MM}/{dd}/{HH}.
  • Pipeline: list log objects → gunzip → parse W3C TSV (dynamic #Fields mapping) → filter to /<code>/ page views (.html//, assets excluded) → aggregate hits + unique client IPs (bots + non-2xx/3xx filtered).

Changes

  • New pure modules: src/lib/cflog.ts (W3C parser), src/lib/insight.ts (aggregation + log-key date selection).
  • src/lib/aws.ts: getObjectBytes (raw bytes for gzip).
  • src/lib/config.ts + src/commands/init.ts: optional cloudfront logBucket, threaded through both cloudfront resolveConfig branches and imported from the log_bucket_name Terraform output (back-compat: legacy configs → clear re-provision hint).
  • src/commands/insight.ts + src/index.ts: runInsight + insight <code> command (--days / --since).
  • infra/: v2 delivery pipeline + private log bucket + lifecycle + output + log_retention_days var.
  • README.md: usage + privacy notice (IPs stored only in the user's bucket, used only for unique approximation, minimal fields, 30-day expiry).

Testing

  • TDD throughout; new offline tests: test/cflog.test.ts, test/insight.test.ts, test/insight-command.test.ts, plus test/config.test.ts/test/init.test.ts cases.
  • npm run build + npm run typecheck clean. npx vitest run342 passed / 3 skipped / 1 failed, where the single failure is the pre-existing environment-dependent test/skill.test.ts preflight case (fails only when local AWS creds exist; unchanged on main; passes in CI — this branch touches neither that test nor preflight.mjs).

Verification boundary

infra/ could not be terraform validated in CI (no Terraform); schemas verified against provider docs and the committed lock file (aws 6.51.0, which has the aws_cloudwatch_log_delivery* resources). A real terraform apply against an account is a manual pre/post-merge check — the one surface CI structurally can't cover.

Follow-ups (tracked, non-blocking)

Refs #43

🤖 Generated with Claude Code

jkas2016 added 13 commits July 11, 2026 18:49
Design for the first vertical slice of `hostdoc insight <code>`: cloudfront
mode end-to-end (v2 delivery-pipeline logging → dedicated log bucket with
30-day expiry → CLI-side gzip/W3C parse → per-code hits + approx unique
visitors). Records the v1-vs-v2 decision (v2 chosen: ACL-free bucket-policy
delivery fits hostdoc's hardened private OAC buckets) and the metric scope.

Refs #43
TDD, bite-sized 8-task plan for the cloudfront insight slice: pure W3C
parser (T1) + aggregation/log-key selection (T2), getObjectBytes (T3),
config.logBucket + init import (T4), runInsight command (T5), CLI
registration (T6), v2 logging Terraform (T7), README privacy/usage (T8).

Refs #43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant