In the earlier courses, you wrote functions that select and count reviewed feedback, keep the original records behind each count, and set aside pending, incomplete, and duplicate records in a new batch. In this course, you’ll assemble those pieces into a report that someone else can use and question.
Before you touch any code, it’s worth agreeing on what the report should answer. An AI assistant can write a correct function for almost any rule you describe, and it can help you pick one, too. Either way, make sure you understand and agree with the rule, so you can judge whether the report answers the question someone actually asked. That’s what you’ll come back to whenever a number looks surprising.
Imagine handing your report to a support lead who needs to decide which problems to investigate this fortnight. A number is useful only if they know which dates and messages it covers. Your job is to make those choices explicit before turning them into code.
You’ll plan the report, build it in browser exercises, then transfer each checked step to a supplied local app. If you joined here directly, you should already be comfortable selecting records with loops, writing functions that return values, and reading result objects. Write Reusable Reporting Functions and Reuse Your Report on New Data introduce those skills.
This course has its own project download. Keep the previous course’s folder: the new source uses separate topic and status fields instead of label. The connection lesson explains the new contract and supplies a working starting point. The first exercise runs in your browser, with Run Tests and feedback you can use after each edit.
The Brief
Keep this brief open while you work through the next items:
- Question: How many approved feedback messages arrived about each topic in the reporting period, and which messages are they?
- Topics:
"delivery","billing", and"app", spelled exactly like that, in lowercase. - Approved-label policy: A record counts only when its status is exactly
"approved". A"pending"record goes into a separate Needs review list instead. - Period: One reporting period, from March 1 to March 14, 2026, including both days. A supplied helper decides whether a date falls inside it.
- Order of rules: First, your earlier input rules send incomplete and duplicate records to Excluded. Next, records outside the period drop out. Only then does status decide between the count and Needs review. So a pending duplicate goes to Excluded, and a pending record from March 20 appears nowhere.
- Output: For each topic, a count plus the IDs and messages behind it, a Needs review list, and an Excluded list that gives the reason for each exclusion.
- Unit: The report counts messages, not customers.
That last line is easy to skim past. If a customer writes about a late parcel twice, the delivery count goes up by two. That’s fine, as long as whoever reads the report knows it.
Copy this brief into a text file or note of your own. You’ll update your copy when the brief changes later in the course.
Unlike the previous course’s whole-batch report, this report answers a question about one period. Input exclusions are checked across the entire batch, while counts and Needs review cover only that period. An out-of-period record is not an input error. Do not add these lists together and expect the batch’s size; inspect the app’s Source batch panel to find records outside the report.
The new loader checks required fields in this order: id, customer, date, text, topic, status. A missing, null, or empty value is excluded. Among complete records, it keeps the first record with a particular customer, date, topic, status, and text, excluding later exact copies.
Unknown nonempty topics or statuses are left for your rules to interpret. A value your rules don’t recognize may appear only in Source batch: that is a limitation to explain at hand-over, not proof the source record was deleted.
Checking the Brief Against Some Records
Take a look at these five records and work out what the brief says the delivery count should be:
| ID | Customer | Date | Topic | Status | Message |
|---|---|---|---|---|---|
| m01 | C-17 | 2026-03-02 | delivery | approved | My parcel arrived a week late. |
| m02 | C-17 | 2026-03-09 | delivery | approved | Late again, and the box was crushed. |
| m03 | C-04 | 2026-03-05 | delivery | pending | Where is my order? |
| m04 | C-22 | 2026-03-11 | billing | approved | I was charged twice this month. |
| m05 | C-09 | 2026-03-16 | delivery | approved | The courier left it in the rain. |
The delivery count is two, from m01 and m02, even though both came from the same customer. The record m03 goes into Needs review, and m05 arrived after March 14, outside the period.
The Plan
You’ll build the report in steps:
- Compose your existing functions into one report function.
- Connect that function to the supplied report app.
- Count only the records inside the reporting period.
- Compare two periods of equal length, as an extension.
- Keep the matching messages with each count and list the pending and excluded records.
- Adapt one rule with an AI suggestion and check the result.
- Track down a surprising count and fix it yourself.
- Hand over your report with usage instructions, an example input and its result, and one concrete limitation of what it shows.
If step 4 has to wait, your report is still useful: topic counts you can trace back to messages, plus clear rules for what was left out.
In the next item, Compose Your Report Functions, you’ll start with step 1.