Template:POFMA-direction-cargo
- Design reference for the {{POFMA-direction-cargo}} template and its backing Cargo table `pofma_directions`. This replaces the flat `{| class="wikitable sortable"` table previously used on POFMA directions. Follows the no-Lua, declare/store pattern documented in `politicalsg-wiki-structure.md` §§2–3.
Why this needed a Cargo redesign
The flat wikitable on the live POFMA page stores nothing queryable: it cannot be filtered by ministry, cross-referenced against an MP's appointment history, or linked to the multiple simultaneous directions that often accompany a single underlying falsehood (e.g. the four directions issued together on 22 January 2020 over the Changi Prison execution-method allegations). The source spreadsheet this schema is drawn from already tracks the data relationally — a directions table, a ministers roll-up, a targeted-entities roll-up, and a topics roll-up — which is exactly what Cargo is for.
Naming convention
`direction_id` is `pofma-{issue_date}-{target-slug}`, with a trailing `-2`, `-3`, etc. appended where the same ministry issues more than one direction to the same target on the same date (e.g. the three separate December 2019 directions to the Singapore Democratic Party, each over a different post). This follows the existing Change ID convention (entity-id + type + year) in `politicalsg-template-reference.md`, adapted since a direction's "entity" is really the recipient, not a single evolving record.
`incident_id` is a second, optional slug that groups multiple `direction_id` records issued over the same underlying falsehood, regardless of date or recipient — e.g. `changi-prison-execution-allegations-2020` links the four 22 January 2020 directions to Lawyers for Liberty, Kirsten Han, The Online Citizen, and Yahoo Singapore. This is the same "design for shared linkage from the outset" principle already applied to Hansard/case-law tables — retrofitting it later would mean re-touching every existing record.
The template
``` This template defines the table "pofma_directions". View table.
Field reference
| Field | Type | Required | Notes |
|---|---|---|---|
| direction_id | slug | Yes | Permanent. `pofma-{issue_date}-{target-slug}`, e.g. `pofma-2019-11-13-brad-bowyer`. Never changed once set. |
| incident_id | slug | No | Groups directions over the same underlying falsehood. Leave blank for a standalone direction. |
| direction_type | enum | Yes | `Correction Direction` / `Targeted Correction Direction` / `General Correction Direction` / `Disabling Order` / `Access Blocking Order` / `Declared Online Location` / `Conditional Warning`. See §Schema limits for the "Media Statement" edge case. |
| issue_date | YYYY-MM-DD | Yes | Date the direction itself was issued. |
| post_date | YYYY-MM-DD | No | First date of the target post/material. Blank where not applicable (e.g. platform-directed TCDs, ISP-directed ABOs). |
| days_between | integer as string | No | Days between `post_date` and `issue_date`. Carried over from the source spreadsheet rather than computed, since some rows have no `post_date` to compute from. |
| ministry_id | ministry slug | Yes | Must match the `ministries` table, e.g. `mha`, `mom`, `moh`. See §Ministry slugs below for disambiguation. |
| issuing_minister | mp_id slug | No | Blank when `alternate_authority=yes`. |
| alternate_authority | Yes | `yes` / `no`. `yes` during election periods when a senior official, not the Minister, is authorised to act (see s52 POFMA). | |
| target_name | text | Yes | Display name of the individual, entity, party, platform, or ISP category targeted. |
| target_id | slug | No | Cross-reference to an `entity_id`, `party_id`, or `mp_id` if a wiki page exists for the target. Leave blank otherwise — do not invent a slug for a person with no page. |
| target_type | enum | Yes | `Individual` / `Media Entity` / `Political Party` / `Platform` / `Internet Service Provider`. |
| platform | text | No | Where the targeted material was communicated, e.g. `Facebook`, `Website`. Distinct from `target_name`: a Targeted Correction Direction's target IS the platform (e.g. `target_name=Facebook`, `platform=Facebook`), whereas an ordinary Correction Direction's target is a person or entity whose post appeared ON a platform (e.g. `target_name=Brad Bowyer`, `platform=Facebook`). |
| subject_summary | text | Yes | One-line factual description of the underlying falsehood. Editorial precis, not a verbatim quotation of the press release. |
| topic_tags | text | No | Comma-separated, e.g. `COVID-19, Legal enforcement`. Matches the "Key subject" roll-up in the source spreadsheet. |
| source_pdf | text | No | Filename of the POFMA Office press-release PDF, where known. |
| source_url | URL | No | Direct link to the direction or press release, where publicly available. |
| verified | enum | Yes | `yes` / `no`. |
| last_updated | YYYY-MM-DD | Yes | Date of data entry, not the direction's issue date. |
Ministry slugs used in this table
`mof` = Ministry of Finance; `mfa` = Ministry of Foreign Affairs; `mha` = Ministry of Home Affairs; `mom` = Ministry of Manpower; `moe` = Ministry of Education; `mci` = Ministry of Communications and Information (renamed MDDI in 2023 — see the ministry_changes table for that record; `ministry_id` stays `mci` per the permanent-ID rule); `moh` = Ministry of Health; `mti` = Ministry of Trade and Industry; `mnd` = Ministry of National Development; `mlaw` = Ministry of Law; `msf` = Ministry of Social and Family Development; `mot` = Ministry of Transport; `pmo` = Prime Minister's Office. Note `mof` (Finance) vs `mfa` (Foreign Affairs) is a deliberate disambiguation from the existing `mfa` example in `politicalsg-template-reference.md` — do not confuse the two.
The People's Association issued directions directly in March 2020 (before the Alternate Authority provisions were relied on more generally); it is a statutory board, not a ministry, so has no `ministries` table entry. Until an `entities` record exists for it, leave `ministry_id` blank for those rows and note the issuing body in `subject_summary` instead of forcing it into a field it doesn't fit.