| Duration | ~55 min in the lesson + ~25 min homework |
| Prerequisites | Checkpoint lesson-5.4; the Telegram bot or email sending from 4.5; the browser connection from 1.6. |
| Checkpoint | lesson-5.5 |
What you will have
The student can attach follow-up tasks with a due date to any lead, sees due and overdue tasks at /admin/today, and receives a daily summary by Telegram or email from a scheduled job on Vercel that is protected by a secret.
Video
The video for this lesson is not recorded yet.
Prompts used in this lesson
Part 3 — Building tasks and the today view
Add follow-up tasks to the CRM and build the Today page. Purpose: the owner must see, every day, whom to contact, and no open lead should be left without a next step. Context: docs/crm-spec.md, the lead_tasks table, the lead card and admin layout from earlier lessons. Lead card: a new "Tasks" section. Add a task with a title and a due date (default: tomorrow). List this lead's tasks: open ones first, by due date; done ones below with the completion time. Open tasks have a "Done" checkbox. Today page at /admin/today, replacing the placeholder: - two groups: "Overdue" (due date before today, not done), oldest first, and "Due today" (due date equals today, not done); - "today" is the current date in the business time zone from the spec; - each row: the task title, the lead's name linking to the lead card, the status badge, the due date, the Call button if the lead has a phone, and a "Done" checkbox; - ticking "Done" records the completion time and then asks "What is the next step?" with a title, a due date and a "No next step" choice; - when nothing is due: a clear "Nothing due today" message; - the sidebar link "Today" shows the number of due plus overdue tasks. Constraints: server-side reads and writes for the signed-in owner only. No new libraries without asking. Before you report, verify in a real browser using the browser connection; when the login page appears, wait while I sign in myself. Check and report on each: tasks due today, yesterday and tomorrow on a sample lead appear under "Due today", under "Overdue", and only on the lead card; ticking one done and creating a next step removes the old task from Today and adds the new one to the lead card; the sidebar count is right; everything survives a reload and is in lead_tasks; phone width. Run the build. Say what you could not verify.
Part 6 — Building and testing the summary
Add a daily summary of follow-up tasks, sent automatically every morning. Purpose: the owner is told whom to contact today even without opening the CRM. Context: the project is hosted on Vercel. First read Vercel's current Cron Jobs documentation and follow it; tell me which pages you read. The code from lesson 4.5 already sends Telegram messages and email. CRON_SECRET is already in .env.local and in the Vercel project. Never print its value. Build: - an endpoint at /api/cron/daily-summary that answers GET requests. It first checks that the Authorization header equals "Bearer " plus CRON_SECRET; if the variable is missing or the header does not match, it returns 401 and does nothing else; - it finds open tasks that are overdue or due today, using exactly the same definition and time zone as the Today page (share the code, do not copy it). There is no signed-in user here, so read the database with the server-only secret access set up in section 4, which must never reach the browser; tell me which existing server code you reused for this; - it sends one message through Telegram, reusing the existing sending code: the date, the counts, then each task as "lead name — task title", overdue first, each with a link to its lead card on the production domain. No phone numbers or emails. If nothing is due: "No follow-ups due today"; - it returns the counts only; - a vercel.json entry that schedules this path once a day at 07:00 UTC. Constraints: one run per day at most. If sending fails, return an error status so the failure shows in Vercel's logs. Verify before you report: with the local site running, call the endpoint without the header and confirm 401; call it with the header, taking the value from .env.local without displaying it, and confirm success; tell me the counts so I can compare them with the Today page and the message I receive. Open the Today page in the browser and compare too. Run the build.
Do along
- Pause after Part 3. Run the tasks prompt from Part 3. Add three tasks to sample leads: due yesterday, today and tomorrow.
- Pause during Part 5. Generate a random value of at least 16 characters and save it as
CRON_SECRETin.env.localand in your Vercel project's environment variables. Do not paste it into Claude. - Pause at the prompt in Part 6. Run the summary prompt. Replace "Telegram" with "email" if that is your channel from 4.5. Set the schedule's hour for your time zone, in UTC.
- Commit, push, find the job in the Vercel project settings, and trigger it once by hand.
- Do the "Check your work" steps, then run the tag commands that end the lesson.
Check your work
- On a sample lead, add a task due today. Open
/admin/today. Expected: the task is under "Due today". - Open
/api/cron/daily-summaryin your browser, locally and on your live domain. Expected: an "unauthorized" response, and no message sent. - Ask Claude: "Trigger the daily summary locally with the secret, without showing the secret." Expected: a Telegram message or email listing the same tasks as the Today page, including the one due today.
- In the Vercel project settings, open Cron Jobs. Expected: one job, path
/api/cron/daily-summary, your schedule. - Trigger the job by hand on production. Expected: the same message arrives.
- Tick the task done and choose "No next step". Reload. Expected: gone from Today, shown as done on the lead card.
Common problems
- The deployment fails with a message that Hobby accounts are limited to daily cron jobs. → The schedule runs more than once a day. → Use a once-a-day expression such as
0 7 * * *. - Local test works, production returns 401. →
CRON_SECRETis missing in Vercel, or was added after the last deployment. → Add it, then redeploy. - The summary says nothing is due, but Today shows tasks. → The endpoint cannot read the database, or uses a different "today". → "The summary and the Today page disagree. Make both use the same code and time zone, and check the endpoint's server-only access."
- No message and no error. → Open the job's logs from the Cron Jobs settings and give Claude the log text.
Homework
About 25 minutes, plus a one-minute look the next morning, on your own, after the lesson. No later lesson depends on it.
- Your follow-up rules. Write how soon you first contact a new lead, how many attempts you make, how many days apart, and when you mark the lead lost. Deliverable: a section "Follow-up rules" in
docs/crm-habits.md(your own notes; create it if missing). Done when: the rules answer the question "what do I do with a lead who has not replied twice?" - A next step for every qualified lead. Give each sample lead in Qualified that has no open task one, with due dates over the coming week. Deliverable: the tasks. Done when: every card in Qualified shows an open task.
- The first morning. Tomorrow, check that the summary arrived without you triggering it and note the time. If the hour does not suit you, change it in
vercel.json(UTC, still once a day). Deliverable: the time, in the same file. Done when: one summary you did not trigger has arrived.
If a task changed files in the project, commit and push without a tag.
Save your work
git add -A
git commit -m "Lesson 5.5: follow-up tasks, Today page, scheduled daily summary"
git tag lesson-5.5
git push
git push --tags