Capability template for analytics and reporting

Dataset profile

Before anyone joins or relies on a new export, the analyst gets one profile of it: what one row stands for, where keys repeat, what is missing, which values look odd, and a numbered list of questions for the data owner. No data is changed and no verdict is given.

Put this on your planBuild this in a sprint

Add it to a workflow in the Fully Powered Planner, beside the teams and roles that will run it. Book a fit call

The outcome

An unfamiliar table stops being a surprise. Before the first join, the analyst has a page that says what a row is meant to be and whether the data bears that out, which keys appear more than once and in what way the repeats differ, which columns hold blanks or stand-in text, which values sit far from the rest, and where two columns disagree with each other. Every finding points to the line in the file where it can be seen.

Each finding that needs an answer from someone else becomes a question addressed to the data owner, with the lines beside it, so the conversation with the source team starts with facts. The profile also notes which findings touch the use the analyst has in mind, and lists the decisions that remain open.

The analyst decides what to clean, what to exclude and whether the data is usable. The profile changes no row, removes none and states no business conclusion.

Who starts the work, and when

An analyst starts it when a new extract arrives, or before relying on a table inherited from someone else, for example a file received during a handover, an acquisition or an investor data request. It is also worth running when a familiar export changes shape. The analyst supplies the file and what it is for, and reads the result before anything is joined, loaded or reported on.

What they supply

  • The extract itself, as a CSV or a pasted table. If it is a sample, say so.
  • Schema notes, one line per column: its name, what it means, its type and any allowed values. A column's absence from the notes is itself a finding.
  • The expected key, the columns that should make a row unique, and the join key if it differs.
  • The intended use, in a sentence, so the profile can say which findings touch it.
  • Optional settings: the period the dates should fall in, the far-out rule, columns that hold personal data, and who owns the data.

What comes out

One profile in a fixed order: the file and its header check, row grain, duplicates, missing and stand-in values, types and formats, value spreads, consistency rules, what the findings touch for the intended use, questions for the data owner, decisions for the analyst, and what was not checked. A section with nothing to report says what was checked and found nothing.

An invented example

Illustrative example with invented data. The company, the file, the people and every row below are invented. The company is an invented online homeware shop, called Shop M here. Its analyst has received a month of order lines from the shop's order system and wants to join them to a returns table. First come the inputs the analyst supplied, in full, then the profile the capability returned.

The inputs

1. Settings (typed by the analyst)

File: order_lines_oct2026.csv (the full October export, not a sample)
Today: Tuesday 10 November 2026
Intended use: join to the returns table on order_id and sku, to look at returns by channel
Expected key: order_id + line_no (one row per order line)
Join key: order_id + sku
Expected period: order_date from 1 October 2026 to 31 October 2026
Far-out rule: more than 10 times the column median
Personal-data columns: none
Data owner: Operations lead
Identifier column: order_id
Consistency rules: ship_date on or after order_date

2. Schema notes (one line per column)

column,meaning,type,allowed
order_id,Order number,whole number,
line_no,Position of the line within the order,whole number,1 or more
order_date,Date the order was placed,date YYYY-MM-DD,
sku,Product code,text,
qty,Units ordered,whole number,1 or more
unit_price,Price per unit in USD,number,0 or more
line_total,qty times unit_price in USD,number,
country,Ship-to country,two-letter code,US or CA or GB
channel,Where the order was placed,text,web or market
ship_date,Date the line was shipped,date YYYY-MM-DD,filled for every line

3. The extract: order_lines_oct2026.csv (header is line 1)

order_id,line_no,order_date,sku,qty,unit_price,line_total,country,channel,ship_date
5001,1,2026-10-01,SKU-100,2,12.50,25.00,US,web,2026-10-03
5001,2,2026-10-01,SKU-205,1,40.00,40.00,US,web,2026-10-03
5002,1,2026-10-02,SKU-100,1,12.50,12.50,CA,web,2026-10-05
5003,1,2026-10-02,SKU-310,3,8.00,24.00,US,market,2026-10-04
5004,1,2026-10-03,SKU-205,1,40.00,40.00,US,web,2026-10-06
5004,2,2026-10-03,SKU-100,4,12.50,50.00,US,web,2026-10-06
5005,1,10/04/2026,SKU-310,2,8.00,16.00,US,Web,2026-10-07
5006,1,2026-10-05,SKU-205,1,40.00,40.00,GB,web,2026-10-09
5006,1,2026-10-05,SKU-205,1,40.00,40.00,GB,web,2026-10-09
5007,1,2026-10-06,SKU-410,2,19.00,38.00,US,market,
5008,1,2026-10-06,SKU-100,1,12.50,12.50,US,web,2026-10-08
5008,2,2026-10-06,SKU-310,1,8.00,8.00,US,web,2026-10-08
5009,1,2026-10-07,SKU-205,2,40.00,80.00,CA,web,2026-10-10
5010,1,2026-10-08,SKU-410,1,19.00,19.00,,web,2026-10-11
5011,1,2026-10-09,SKU-100,3,12.50,37.50,US,web,2026-10-12
5011,2,2026-10-09,SKU-310,1,8.00,9.00,US,web,2026-10-12
5012,1,2026-10-10,SKU-205,1,40.00,40.00,US,market,2026-10-08
5013,1,2026-10-12,SKU-100,500,12.50,6250.00,US,web,2026-10-14
5014,1,2026-10-13,SKU-410,1,19.00,19.00,US,web,2026-10-16
5015,1,2026-10-14,SKU-310,2,8.00,16.00,N/A,web,2026-10-17
5016,1,2026-10-15,SKU-205,-1,40.00,-40.00,US,web,2026-10-15
5017,1,2026-09-30,SKU-100,2,12.50,25.00,US,web,2026-10-02
5018,1,2026-10-20,SKU-410,1,19.00,19.00,US,web,2026-10-23
5004,2,2026-10-03,SKU-310,2,8.00,16.00,US,web,2026-10-06

The profile

DATASET PROFILE: order_lines_oct2026.csv

For: the analyst. Prepared 10 November 2026 from the settings, schema notes and extract supplied. Intended use: join to the returns table on order_id and sku, to look at returns by channel.

1. THE FILE
Header check: the 10 headers match the 10 columns in the schema notes, in the same order. 24 data rows, 10 columns; every row has 10 fields. Full export, as stated; the figures describe the rows supplied.

2. ROW GRAIN
Expected: one row per order line, key order_id + line_no. 22 distinct keys among 24 rows. The grain does not hold: 2 keys appear more than once (5004 / 2 on lines 7 and 25; 5006 / 1 on lines 9 and 10).
Identifier order_id: 18 distinct values.
Join key order_id + sku: 23 distinct among 24 rows. 1 repeat: 5006 / SKU-205 on lines 9 and 10.

3. DUPLICATES
Identical rows: 1 pair, lines 9 and 10 (order 5006, line 1).
Same key, different values: 5004 / 2 on lines 7 and 25. They differ in sku (SKU-100, SKU-310), qty (4, 2), unit_price (12.50, 8.00) and line_total (50.00, 16.00); they agree in order_id, line_no, order_date, country, channel and ship_date.

4. MISSING AND STAND-IN VALUES
country: 1 blank (line 15); 1 stand-in, "N/A" (line 21). 22 of 24 rows hold a value.
ship_date: 1 blank (line 11). 23 of 24 rows hold a value. The notes say it is filled for every line.
No blank or stand-in values in order_id, line_no, order_date, sku, qty, unit_price, line_total, channel.

5. TYPES AND FORMATS
order_date: 23 of 24 values are YYYY-MM-DD. Line 8 reads 10/04/2026, which is either 4 October 2026 or 10 April 2026; it is left unread.
channel: "Web" on line 8 differs from "web" only in capitalisation.
country: apart from the blank and the "N/A" above, every value is a two-letter code.
order_id, line_no, qty: whole numbers throughout. unit_price, line_total: plain numbers throughout, no symbols. sku: "SKU-" and three digits throughout. ship_date: all 23 filled values are YYYY-MM-DD. No leading or trailing spaces found in any column.

6. VALUES AND SPREADS
line_no: min 1, median 1, max 2. 0 negative; 0 zero. Far-out (above 10): none.
qty: min -1, median 1, max 500. 1 negative (line 22); 0 zero. Far-out (above 10): line 19 (500).
unit_price: min 8.00, median 12.50, max 40.00. 0 negative; 0 zero. Far-out (above 125.00): none.
line_total: min -40.00, median 24.50, max 6250.00. 1 negative (line 22); 0 zero. Far-out (above 245.00): line 19 (6250.00).
order_date (23 readable): earliest 2026-09-30, latest 2026-10-20. Outside 1 to 31 October 2026: line 23 (2026-09-30). After 10 November 2026: none. Line 8 falls inside the period if read as 4 October and outside it if read as 10 April.
ship_date (23 readable): earliest 2026-10-02, latest 2026-10-23. After 10 November 2026: none.
sku (4 distinct): SKU-100 7, SKU-205 7, SKU-310 6, SKU-410 4. Outside the allowed list: no list given. Values seen once: none.
country (4 distinct, counting "N/A" and not the blank): US 18, CA 2, GB 2, N/A 1; plus 1 blank. Outside the allowed list (US, CA, GB): lines 15 and 21. Values seen once: "N/A" (line 21).
channel (3 distinct as written): web 20, market 3, Web 1. Outside the allowed list (web, market): line 8 ("Web"). Values seen once: "Web" (line 8). With capitals ignored: web 21, market 3.

7. CONSISTENCY RULES AND ALLOWED VALUES
ship_date on or after order_date (rule given by the analyst): 22 tested, 21 pass. Fail: line 18 (5012): ship_date 2026-10-08 is before order_date 2026-10-10. Left out: line 8 (order_date unread) and line 11 (no ship_date).
line_total = qty x unit_price (defined in the notes): 24 tested, 23 pass. Fail: line 17 (5011 / 2): 1 x 8.00 = 8.00, but line_total is 9.00. Left out: none.
Allowed values in the notes, one line per column that has a limit or list:
line_no, 1 or more: 24 tested, 24 pass. Not passing: none.
qty, 1 or more: 24 tested, 23 pass. Not passing: line 22 (-1).
unit_price, 0 or more: 24 tested, 24 pass. Not passing: none.
country, US or CA or GB: 24 tested, 22 pass. Not passing: line 15 (blank), line 21 ("N/A").
channel, web or market: 24 tested, 23 pass. Not passing: line 8 ("Web").
ship_date, filled for every line: 24 tested, 23 pass. Not passing: line 11 (blank).

8. WHAT THE FINDINGS TOUCH FOR THE INTENDED USE
The intended use reads order_id, sku and channel for the join and the grouping, and order_date for the period.
Join key order_id + sku: two rows carry the key 5006 / SKU-205 (lines 9 and 10). Any returns row with that key would match both of them; the file does not show whether the returns table holds such a row. Order 5004 has two rows keyed line 2 with different skus (lines 7 and 25); under order_id + sku they are distinct keys (5004 / SKU-100 and 5004 / SKU-310), while under order_id + line_no they collide.
Grouping by channel: line 8 ("Web") would form a separate group from "web" unless the grouping ignores capitals.
Period: line 23 is dated 30 September; line 8's date is unresolved.
Columns the intended use does not read (qty, unit_price, line_total, country, ship_date): the findings on lines 11, 15, 17, 19, 21 and 22 sit on those columns, and line 18 has a ship_date before its order_date.

9. QUESTIONS FOR THE DATA OWNER (Operations lead)
1. Lines 9 and 10 are identical in every field (order 5006, line 1, SKU-205, qty 1, 40.00). Does the export list this order line twice, or were two identical lines recorded?
2. Order 5004 has two rows keyed as line 2: line 7 (SKU-100, qty 4, 50.00) and line 25 (SKU-310, qty 2, 16.00). Which is line 2 of the order, or does one belong to a different line number?
3. Line 8 (order 5005) has order_date 10/04/2026. Which date is meant, and does the export write dates this way anywhere else?
4. Line 8 has channel "Web" where every other web order has "web". Is it the same channel?
5. Line 23 (order 5017) has order_date 2026-09-30 in an export described as October. Why is it included?
6. Line 11 (order 5007, ordered 2026-10-06) has no ship_date, and the notes say it is filled for every line. Has it shipped?
7. Country is blank on line 15 (order 5010) and "N/A" on line 21 (order 5015). What do they mean?
8. Line 17 (order 5011, line 2): line_total is 9.00 where 1 x 8.00 is 8.00. Which figure is the recorded one?
9. Line 18 (order 5012): ship_date 2026-10-08 is two days before order_date 2026-10-10. Are both dates as recorded?
10. Line 19 (order 5013): qty 500 of SKU-100, line_total 6250.00, where the median quantity is 1. What was this order?
11. Line 22 (order 5016): qty -1 and line_total -40.00. What does a negative line stand for?

10. DECISIONS FOR THE ANALYST
1. The repeated keys (lines 7, 9, 10, 25): keep all rows as supplied, hold the affected rows out of the join, correct at source, or wait for answers 1 and 2.
2. The row outside the period (line 23) and the unread date (line 8): keep as supplied, hold out of the period, or wait for answers 3 and 5.
3. The "Web" spelling (line 8): keep as its own group as supplied, or wait for answer 4.
4. Rows that break a rule or the allowed values (lines 17, 18, 19, 22) and the blank and stand-in values (lines 11, 15, 21): keep as supplied, hold out of any figure that uses the field, correct at source, or wait for answers 6 to 11.
Whether the data is usable is the analyst's decision.

11. NOT CHECKED
Whether the values are true to the shop's real orders; whether any order lines are missing from the export; any other table, including the returns table; the meaning of any column beyond the schema notes. No row has been changed, removed or corrected.

Every figure counts the 24 data rows of order_lines_oct2026.csv as supplied on 10 November 2026. This profile changes no data and states no conclusion about the business.

Where it fits

Before a finished workbook is sent out, spreadsheet check before sharing is the one to use. This capability is for a table you are about to start working with.

What has to change for your company

Write your schema notes once per source and keep them: the profile is only as good as the meaning you give each column. Set the far-out rule that suits your data, the stand-in values your systems use for "unknown", and the period you expect. Name the columns that hold personal data so the profile reports counts for them and shows no values. Name the data owner for each source, so every question has an addressee. Decide where profiles are filed. It runs in ChatGPT, Claude, Copilot or Gemini, from a file or pasted rows you supply; it needs no connection to your database, and it never asks for a login.

What has been checked

Fully Powered AI wrote this capability template. It was editorially reviewed on 10 November 2026. It was tried on its invented example in Claude on 10 November 2026; the record is published with it. The first run found that the example tested a date order the instructions did not call for; the template and the example were then changed, and the edited version was run once more on the example by the assistant that made the edits, not independently. That run covered one export with a repeated key, a second date format, a stand-in word and a rule the analyst listed; it did not reach a header that does not match the notes, a column marked as personal data, or a request to clean the file. It has not yet been tested in a client environment. It has not yet been tested as a packaged version in ChatGPT, Claude, Copilot or Gemini.

Testing in your environment means running it on two or three extracts your analysts already know well, with faults planted in copies and written down in advance: a repeated key whose rows differ, a date in a second format, a stand-in word in a numeric column, a column missing from the notes. The analyst confirms each finding against the file before anyone relies on the profile. Pilot acceptance-test preparation sets those cases up, and what we test before we call an AI workflow ready describes the record we keep.

The full capability template

Everything above is the outline. The complete capability template is the working version: the roles, the inputs, the procedure, the exceptions and stop conditions, the output format, the reviewer checklist, the acceptance tests, the instructions for an AI assistant and what to customize for your company. It comes with a download and the link to its folder in Fully Powered’s public repository.

View the full template

Free with an account. Sign in by email: no password and no card.

Next step

Put this capability to work for your team: on your plan, or built with you in a sprint.

Put this on your plan

Add it to a workflow in the Fully Powered Planner, beside the teams and roles that will run it.

Build this in a sprint

In a sprint, Fully Powered adapts this capability template to your rules, proves it on your own work and puts it in the hands of the roles that own it.

Two ways to begin:

Rather talk it through first? Book a fit callDiscuss adapting this