Skip to content

regenrek/offernow

Repository files navigation

OfferNow

OfferNow offer overview screenshot

OfferNow is a small, password-protected offer viewer. It turns a private folder of Markdown documents into a client-facing offer page with a document table of contents and an "Angebot ansehen" call-to-action for the signing flow.

It is designed for sending polished, read-only offer material without publishing the offer content itself. The public homepage does not list offers; each offer is reachable only through its /o/<slug> URL and password gate.

For your Coding Agents

Use the $offernow-create-offer skill to create a new offer with Cursor, Codex, Claude, or another coding agent.

Stack

  • Astro 5 with output: "server" and the Cloudflare adapter.
  • Tailwind CSS 4 for styling.
  • Alchemy for Cloudflare Worker provisioning.
  • Astro content collections for Markdown offer documents.
  • pnpm for package management.

Content Model

Each offer has two parts:

  • Source configuration in src/offers.config.ts, containing the offer slug, display title, client, and docusealUrl.
  • Private Markdown content under src/data/offers/<slug>/.

Real offer Markdown lives under src/data/offers/ locally. That directory is gitignored by default so private client documents are not published with the open-source repository.

Example document layout:

src/data/offers/clientabc/
  dokument-1.md
  dokument-2.md
  leistungsumfang.md

Each document is a Markdown file with frontmatter:

---
title: "Leistungsumfang"
order: 1
description: "Kurzbeschreibung des Dokuments."
---

## Abschnitt

Generischer Beispieltext fuer das Angebotsdokument.

Auth Model

OfferNow uses one password per offer. Passwords are read on the server from environment variables and are never stored in src/offers.config.ts.

  • OFFER_SESSION_SECRET signs the httpOnly offer session cookie.
  • OFFER_CLIENTABC_PW is the password for the example /o/clientabc offer.
  • General convention: OFFER_<SLUG_UPPER>_PW; non-alphanumeric slug characters become underscores, e.g. client-abc uses OFFER_CLIENT_ABC_PW.

After a successful login, the server sets a signed httpOnly cookie for that offer. Document routes remain blocked unless the cookie is valid.

Local Setup

  1. Install dependencies with pnpm install.
  2. Copy .env.example to .env.
  3. Set OFFER_SESSION_SECRET to a long random value.
  4. Add one OFFER_<SLUG_UPPER>_PW value for each local offer.
  5. Run checks or builds with pnpm exec astro check and pnpm run build.

The dev server is intentionally not required for repository verification.

Adding Offers

Use the project skill at .cursor/skills/offernow-create-offer/SKILL.md when creating a new offer. It documents the repeatable process:

  1. Choose a deploy-safe slug such as clientabc or client-abc.
  2. Add private Markdown documents under src/data/offers/clientabc/.
  3. Register the offer in src/offers.config.ts.
  4. Add OFFER_CLIENTABC_PW or the matching underscore-normalized key to .env.
  5. Verify with pnpm exec astro check and pnpm run build.

Example registry entry:

{
  slug: "clientabc",
  title: "Angebot - Client ABC",
  client: "Client ABC",
  docusealUrl: "https://example.com/sign/clientabc",
}

Routes

  • / is a minimal public landing page with no offer list.
  • /o/[offer] renders the password gate or the authenticated offer overview.
  • /o/[offer]/[doc] renders one authenticated offer document.
  • /api/offer-login validates offer passwords and sets the session cookie.

Deployment Notes

alchemy.run.ts provisions the Cloudflare Worker. Deploy manually from a trusted local environment after alchemy login and .env are configured:

pnpm deploy:alchemy

Deploy-time secrets are read from local environment variables:

  • ALCHEMY_PASSWORD
  • CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID, when not using OAuth
  • OFFER_SESSION_SECRET
  • one OFFER_<SLUG_UPPER>_PW value per deployed offer

There is intentionally no GitHub deploy workflow.

Open-Source Safety

  • Do not commit .env or real passwords.
  • Do not commit real client offer Markdown.
  • Keep src/data/offers/ ignored unless you intentionally add sanitized sample content.
  • Keep src/offers.config.ts empty or populated only with clearly fake examples in the public repository.
  • Share offer passwords out-of-band, never in URLs or public issue trackers.

About

Password-protected client offer boxes: markdown offer documents rendered with Astro, deployed via Alchemy on Cloudflare.

Resources

License

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors