Files
fuel-alert/docs/superpowers/specs/legal-pages-spec.md
Ovidiu U ecd45588e9
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
Add legal policy pages and shared layout component
- Add Cookie Policy view documenting essential cookies (session, CSRF, remember_me, fa_location) and cookieless Umami analytics
- Add Privacy Policy view covering UK GDPR compliance, data categories, lawful bases, processors, retention, and user rights
- Add Refund & Cancellation Policy view explaining 14-day cooling-off period under Consumer Contracts Regulations 2013 and express-consent flow
- Add Terms of Service view defining account rules, subscription billing, and governing law
- Create shared legal layout component with FuelAlert header, footer with cross-links, and consistent typography
- Add feature tests covering all four legal pages and their cross-links
- All policies include placeholders for ICO registration number, email, and hosting/email providers pending production config
2026-05-14 17:43:53 +01:00

20 KiB
Raw Blame History

FuelAlert — Legal Pages Spec

Context for Claude Code

You are generating four legal pages for FuelAlert, a UK consumer subscription web/mobile app that shows real-time UK fuel prices and forecasts.

Reference comparable (structural check, NOT for copying)

A near-identical business already exists and has competent legal pages: Fuel Finder UK at https://www.fuel-finder.uk, operated by Scott Benson as a UK sole trader. Same business model, same data sources, same jurisdiction.

Use it ONLY as a structural sanity check. Do not copy any text. Their content is copyrighted and their specific processors / retention periods / business decisions are not FuelAlert's.

What Fuel Finder UK does well that this spec already incorporates:

  • Explicit sole trader disclosure naming the operator
  • Named ICO registration number in the Privacy Policy
  • Specific named processors (Stripe, hosting provider, email provider, analytics, mapping services) with what data flows to each
  • Strong price-accuracy disclaimer in Terms ("prices may not reflect real-time changes, always verify at the pump")
  • "AS IS" / "AS AVAILABLE" basis with liability limitations
  • ICO complaint route clearly stated
  • Account deletion flow that cancels paid subscription first

What FuelAlert must do BETTER than Fuel Finder UK:

  • Standalone Refund & Cancellation Policy page — Fuel Finder UK appears to bundle this into Terms. Stripe specifically asks for a refund policy; keep it as a separate page at /legal/refund.
  • Express-consent checkbox at subscription checkout for the 14-day cooling-off period under Consumer Contracts Regulations 2013 (see Refund Policy section below). This is the single most important implementation detail in the entire spec.

If you find yourself generating content that overlaps verbatim with Fuel Finder UK or any other site, stop and rewrite in your own words. Legal pages are copyrighted works.

Business operator (data controller):

  • Name: Ovidiu Ungureanu
  • Trading as: FuelAlert
  • Status: Sole trader (not a limited company — do not use "Ltd", "Limited", or any corporate form)
  • Location: Peterborough, United Kingdom
  • Contact email: [hello@fuelalert.co.uk]
  • ICO registration number: [PLACEHOLDER: ZAxxxxxxx — Ovidiu to register at ico.org.uk before launch, fee ~£40/yr]

Service:

  • UK fuel price comparison and forecasting
  • Free tier + two paid subscription tiers: Daily (£0.99/mo) and Smart (£2.49/mo); annual billing also offered
  • Data sources: UK government Fuel Finder / Pump Watch open data, ONS Postcode Directory (OGL/Crown Copyright)
  • Processes: email address, postcode/location data, account credentials, payment data (via Stripe), usage telemetry

Jurisdiction:

  • England and Wales
  • Consumer law: Consumer Rights Act 2015, Consumer Contracts (Information, Cancellation and Additional Charges) Regulations 2013 ("CCRs")
  • Data protection: UK GDPR + Data Protection Act 2018, PECR for cookies/marketing
  • Digital markets: Digital Markets, Competition and Consumers Act 2024 ("DMCC")

Tech stack & integration:

  • Laravel + Blade for server-rendered pages (NOT Vue components — these must render in raw HTML for Stripe reviewers and SEO)
  • Route prefix: /legal/*
  • Layout: extend the existing site layout but with a readable prose container (max-width ~720px, generous line-height)
  • Each page has a last_updated date in front matter — set to today
  • All pages must be linkable from the footer and accessible without JavaScript

⚠️ CRITICAL: Server-rendered Blade only, NOT Vue

The rest of this application is a Vue SPA. That is irrelevant for these pages. The legal pages must be server-rendered Blade templates.

Rules:

  • Files live at resources/views/legal/{name}.blade.php — never .vue
  • Body content must be plain HTML with Blade directives (@extends, @section, {{ }})
  • No Vue components anywhere in the page body — no custom tags like <legal-privacy-page>, no <div id="app">, no Vue mounting points
  • No client-side rendering for the legal content itself — Alpine.js is acceptable only for the cookie banner show/hide behaviour, nothing else
  • Pages must work fully with JavaScript disabled

Verification test (run after generation):

curl -s https://[host]/legal/privacy | grep -i "data controller"
curl -s https://[host]/legal/terms | grep -i "subscription"
curl -s https://[host]/legal/refund | grep -i "14-day"
curl -s https://[host]/legal/cookies | grep -i "essential"

Each command must return matching lines from the raw HTML response. If any returns empty, the page has been built as a client-rendered component and must be redone as Blade.

If you find yourself reaching for <script> tags, Vue single-file components, or any pattern that requires the browser to execute JS before content appears — stop and use plain Blade instead.


Pages to generate

  1. /legal/privacy — Privacy Policy
  2. /legal/terms — Terms of Service
  3. /legal/refund — Refund & Cancellation Policy (can be a section of Terms, but a separate page is cleaner for Stripe review)
  4. /legal/cookies — Cookie Policy (paired with a real consent banner — see separate section)

1. Privacy Policy (/legal/privacy)

Required sections, in order:

1. Who we are

  • Identify Ovidiu Ungureanu as data controller, trading as FuelAlert
  • Sole trader status, Peterborough address (use generic "Peterborough, UK" unless a registered business address is provided)
  • ICO registration number
  • Contact email for privacy queries

2. What data we collect Break into clear subsections:

  • Account data: email, hashed password, account creation date
  • Location data: postcodes entered, optional precise GPS if granted, derived location for nearby-station queries
  • Payment data: handled by Stripe; FuelAlert does NOT store card numbers. Stripe customer ID and subscription metadata only.
  • Usage data: features used, queries made, price alerts configured (for service delivery and improvement)
  • Technical data: IP address, browser type, device type (for security and analytics)
  • Marketing preferences: only if user opts in

3. Lawful basis for processing For each category, state the UK GDPR Article 6 basis:

  • Account + service delivery: contract (Art. 6(1)(b))
  • Payment processing: contract
  • Security/fraud prevention: legitimate interests (Art. 6(1)(f))
  • Analytics/product improvement: legitimate interests, with opt-out via cookie banner
  • Marketing emails: consent (Art. 6(1)(a))

4. How we use your data Bullet list, plain English. Tie back to the lawful basis for each use.

5. Who we share data with (processors) Named list — be specific:

  • Stripe (payment processing) — refer to Stripe's privacy policy
  • [Hosting provider, e.g. Hetzner] (infrastructure) — EU-based, note location
  • [Email provider, e.g. Fastmail / Postmark] (transactional email)
  • [Analytics, e.g. Plausible] — if used; if self-hosted, say so
  • State that we do NOT sell data to third parties

6. International transfers

  • State whether any processors are outside the UK/EEA (Stripe has US operations)
  • Reference appropriate safeguards: Standard Contractual Clauses (SCCs) and UK International Data Transfer Addendum

7. How long we keep data

  • Active account data: while account is active + 12 months after closure
  • Payment records: 6 years (HMRC requirement for sole traders)
  • Marketing data: until consent is withdrawn
  • Logs/analytics: max 24 months

8. Your rights under UK GDPR List all eight rights with one-line explanations:

  • Right of access
  • Right to rectification
  • Right to erasure ("right to be forgotten")
  • Right to restrict processing
  • Right to data portability
  • Right to object
  • Rights related to automated decision-making (state we do NOT make solely automated decisions with legal effect)
  • Right to withdraw consent

Explain how to exercise rights (email to the contact address, response within one month).

9. Cookies Brief mention with link to the dedicated Cookie Policy.

10. Security Plain-English summary: HTTPS, hashed passwords, encrypted database fields where appropriate, access controls, regular updates. Don't overpromise ("bank-grade" etc. — meaningless and creates liability).

11. Children Service is not directed at under-16s; we do not knowingly collect data from children.

12. Complaints Right to complain to the ICO: ico.org.uk, 0303 123 1113. Encourage contacting FuelAlert first.

13. Changes to this policy We will notify users of material changes by email; non-material changes shown by updated "Last updated" date.

14. Contact Email address for privacy queries.

Tone & style

  • Plain English, Hemingway readability score ~grade 8
  • No legalese where avoidable
  • Use "we" / "you"
  • Short paragraphs, lots of headings, scannable

2. Terms of Service (/legal/terms)

Required sections, in order:

1. About these terms

  • Who FuelAlert is (sole trader disclosure)
  • These terms form a contract between you and Ovidiu Ungureanu trading as FuelAlert
  • By using the service you agree to these terms
  • Governing law: England and Wales

2. The service

  • What FuelAlert does
  • Free tier and paid tier descriptions
  • We may add, remove, or change features with reasonable notice

3. Your account

  • Eligibility: 18+, UK resident, accurate information required
  • One account per person
  • You're responsible for keeping login credentials secure
  • We may suspend accounts for breach of these terms

4. Subscriptions, billing and payment This is the section Stripe cares most about. Cover:

  • Prices (link to /pricing) — currently £0.99/mo Daily, £2.49/mo Smart, with annual discount
  • Billing cycle: monthly or annual, charged in advance
  • Auto-renewal: subscriptions auto-renew at the end of each period at the then-current price, until cancelled
  • Payment method: card via Stripe; you authorise FuelAlert (via Stripe) to charge your method on each renewal
  • Failed payments: we'll retry and notify you; persistent failure suspends paid features
  • Price changes: 30 days' notice by email before any price increase takes effect on renewal; you may cancel before the increase
  • VAT: prices include UK VAT where applicable (sole traders below the VAT threshold do not charge VAT — clarify FuelAlert's current status)

5. Cancellation and refunds Cross-reference the Refund Policy. Summarise:

  • You can cancel at any time from your account settings
  • Cancellation stops the next renewal; you keep access until the end of the current billing period
  • 14-day right to cancel for new subscribers (see Refund Policy for the express-consent mechanism that affects this)

6. Acceptable use You agree not to:

  • Scrape, reverse-engineer, or bulk-extract data from the service
  • Resell or redistribute price data
  • Use the service for any unlawful purpose
  • Attempt to compromise security
  • Create automated queries beyond normal personal use

7. Accuracy of price data — IMPORTANT This is your liability shield. Say clearly:

  • Prices are sourced from official UK government data feeds (Pump Watch / Fuel Finder) and refreshed periodically
  • We make reasonable efforts to display accurate prices but cannot guarantee prices are correct at the moment you arrive at a station
  • Stations may change prices between data feed updates
  • FuelAlert is not liable for losses arising from inaccurate price data (wasted journey, fuel cost differences, etc.)
  • Always confirm the price at the pump before fuelling

8. Forecasts and predictions

  • Forecasts are informational only and not financial advice
  • Past trends do not guarantee future prices
  • We do not warrant the accuracy of any forecast

9. Intellectual property

  • The FuelAlert name, logo, software, and original content are owned by Ovidiu Ungureanu
  • Underlying fuel price data is owned by the respective retailers and published under government open data schemes; ONS Postcode Directory data is © Crown Copyright, used under Open Government Licence v3.0
  • You get a limited, non-exclusive, revocable licence to use the service for personal, non-commercial purposes (or commercial fleet use if on a Fleet plan)

10. Third-party services We use Stripe for payments. Your use of Stripe is also subject to Stripe's terms.

11. Limitation of liability

  • We don't exclude liability for death/personal injury caused by negligence, fraud, or anything that can't be excluded under UK consumer law
  • We exclude liability for indirect, consequential, or business losses
  • For consumers using the paid service, our total liability in any 12-month period is capped at the amount you paid in subscription fees in that period
  • We don't accept liability for issues caused by third-party services we depend on (Stripe outage, data feed outage, etc.)

12. Termination

  • You can stop using the service and close your account at any time
  • We can terminate access for serious breach of these terms, with notice where reasonable
  • On termination, paid sections 411 of these terms survive

13. Changes to these terms We may update these terms; material changes notified by email at least 14 days before they take effect.

14. Disputes

  • Try to resolve directly by contacting us first
  • These terms are governed by the laws of England and Wales; courts of England and Wales have non-exclusive jurisdiction
  • Consumers retain the right to bring proceedings in their country of residence
  • Reference to alternative dispute resolution if applicable

15. Contact Email address.


3. Refund & Cancellation Policy (/legal/refund)

This page is required by Stripe specifically and by UK consumer law. Keep it short and clear.

Required sections:

1. Your 14-day right to cancel (cooling-off period)

  • Under the Consumer Contracts Regulations 2013, you have 14 days from the date you subscribe to cancel without giving a reason
  • This applies to new subscribers only; not subsequent renewals

2. Express consent to start the service immediately — CRITICAL CLAUSE

  • When you subscribe, you can choose to start using the paid features immediately
  • By doing so, you expressly acknowledge that you lose your right to cancel once the service has been fully supplied (i.e. once you've used the paid features within the 14-day window)
  • If you cancel before using the paid features, you receive a full refund
  • If you cancel within 14 days having used some paid features, we may reduce the refund proportionally to reflect usage

Implementation note for the signup flow: the express consent must be an unticked checkbox at checkout, with explicit text. Do not pre-tick it. Suggested wording for the checkbox label:

"I want my subscription to start immediately. I understand that by using paid features within the 14-day cooling-off period, I will lose my right to cancel under the Consumer Contracts Regulations 2013."

3. How to cancel

  • From your account: Settings → Subscription → Cancel
  • Or by emailing the contact address
  • Cancellation is effective at the end of the current billing period unless you exercise the 14-day right above

4. Refunds outside the 14-day period

  • After 14 days, subscription fees are non-refundable for the remainder of the period you paid for
  • You keep access until the end of the period
  • We may issue discretionary refunds in cases of service failure or where required by law

5. Annual subscriptions

  • Same 14-day right applies
  • After 14 days, annual fees are non-refundable; no pro-rata refund for unused months

6. Failed payments and involuntary cancellation

  • If your payment fails, we'll retry and notify you
  • Paid features suspend after [N] failed retries
  • Your account is not deleted; you can resume by updating payment

7. How long refunds take

  • Refunds are issued to the original payment method within 510 business days of approval

8. Contact Email address for refund requests.


Required sections:

1. What cookies are One short paragraph.

2. Cookies we use Table format with columns: Name | Purpose | Duration | Type (Essential / Analytics / Marketing).

Categories to include:

  • Essential: session, CSRF, authentication, cookie-consent preference itself — these do not require consent under PECR
  • Analytics: only if you use them; name them specifically (Plausible is cookie-less in many configs, GA4 uses several)
  • Marketing: only if you run any — likely none at launch

--- ignore for now. need to decide what tool to use for this

3. Your choices

  • You can accept, decline, or customise non-essential cookies via the consent banner
  • You can change your choice at any time via "Cookie Settings" in the footer
  • Most browsers also let you block cookies — link to ICO guidance on managing cookies

4. Changes to this policy Standard wording.

5. Contact Email.


Implement as a Blade component, server-rendered, that:

  • Appears on first visit
  • Has three buttons: Accept all, Reject all, Customise
  • "Customise" expands to checkboxes per category (Essential — locked on; Analytics; Marketing if applicable)
  • Stores choice in a first-party cookie (fa_cookie_consent) for 12 months
  • Blocks non-essential scripts from loading until consent is given — this is the critical bit. Use a tag manager pattern or conditional Blade includes; do NOT load Google Analytics, etc. before consent.
  • Persistent "Cookie Settings" link in the footer reopens the customise panel

PECR / ICO require equal prominence for accept and reject. Don't make "Reject" smaller or harder to find.


Implementation notes for Claude Code

  1. Create Laravel routes in routes/web.php:

    Route::view('/legal/privacy', 'legal.privacy')->name('legal.privacy');
    Route::view('/legal/terms', 'legal.terms')->name('legal.terms');
    Route::view('/legal/refund', 'legal.refund')->name('legal.refund');
    Route::view('/legal/cookies', 'legal.cookies')->name('legal.cookies');
    
  2. Create Blade layout resources/views/layouts/legal.blade.php extending the main site layout, with a narrow prose container.

  3. Each page at resources/views/legal/{name}.blade.php should:

    • Set page title
    • Set meta description (short summary, ~150 chars)
    • Render the content in semantic HTML (h1, h2, h3, ul, ol, table where appropriate)
    • Show "Last updated: [date]" at top
    • Use Blade @section for content
  4. Update footer to link to all four legal pages with route() helpers. Replace any existing "Cookie Settings" link with a button that opens the consent banner customise panel.

  5. Cookie banner component at resources/views/components/cookie-banner.blade.php — include in main layout, with Alpine.js or vanilla JS for show/hide logic. Must be functional with JavaScript disabled (degrade to "you can change cookie settings in your browser" message).

  6. Do NOT auto-generate the ICO registration number or contact email. Leave clear [PLACEHOLDER: ...] markers throughout for Ovidiu to fill in before deployment.

  7. Do NOT include claims that aren't true yet — if uncertain, use a [PLACEHOLDER: verify before launch] marker rather than guessing.

  8. At the top of each generated file, add a comment:

    {{-- DRAFT: Generated [date]. Review by UK-qualified solicitor recommended before launch. --}}
    

Pre-launch checklist for Ovidiu (not for Claude Code)

  • Register with the ICO (ico.org.uk) and obtain registration number — required by law for processing personal data commercially
  • Replace all [PLACEHOLDER: ...] markers
  • Confirm hosting provider and processors named in the Privacy Policy are accurate
  • Test the cookie banner: does it block non-essential scripts before consent?
  • Test the signup flow: is the express-consent checkbox unticked by default?
  • Test account cancellation: does it work end-to-end?
  • Have a UK-qualified solicitor review (or use Termly/iubenda as a sanity check)
  • Set last_updated dates to the actual go-live date
  • Submit to Stripe with the live URL