Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/astrxnomo/manizalesdepie/llms.txt

Use this file to discover all available pages before exploring further.

Work orders (necesidades) are the spine of the product. A work order is a single job at a single place — “escombros bloqueando la entrada de dos casas” — that stays on the map until enough people have helped and nobody says it still needs attention. Unlike a site, which is a persistent fixture, a work order is something to be done: it is true until it is not, and the thread of entries is the evidence of what happened between those two states.

Categories

CategorySpanish Label
debris_removalEscombros
animal_rescueRescate de animales
structural_riskRiesgo estructural
suppliesInsumos
otherOtro
supplies covers food, drinking water, and hygiene items — anything a family is asking for rather than a job site asking to be fixed. A former water category existed briefly and was retired: every real case tagged with it described food, water, and shelter together, which is supplies, not a category of its own. The Postgres enum still carries the value, but nothing in the application offers or accepts it.

Status lifecycle

Status is derived from the work_order_update activity thread by the sync_work_order_state Postgres function. The application never writes a status directly. Closing used to be a single anonymous tap, which meant one bad actor could take any case off the map; that path no longer exists.
DB StatusMeaning
unclaimedNo one has said anything about this case
claimedAt least one person said “yo puedo atender”
attendedAt least one person said “ya ayudé” — case is still open
closed_completedA curator closed the case as resolved
closed_by_othersNo longer used in the app flow (kept because the Postgres enum keeps it)
closed_rejectedA curator marked the case as not real
The ordinary path to closing is the database threshold: two distinct phone numbers posting helped entries. No single person can reach that threshold alone, which is the whole point. The curator actions (closed_completed, closed_rejected) are the exception for cases that only one person ever helped with, or that are genuinely fake.

WorkOrderRollup

The public UI does not show raw DB statuses. Instead, it computes a rollup from status, reopened, and helpedCount together (see workOrderRollup in lib/labels.ts):
RollupDescriptionMarker color
untouchedNobody has said anything — the loudest thing on the mapRed (bg-unclaimed)
onTheWaySomebody said “voy”, nobody has been yetSoftened red (bg-unclaimed/75)
partialOne person helped — case is NOT better than half-doneAmber (bg-claimed)
advancedTwo or more people helped, still openSoftened green (bg-resolved/75)
reopened”Sigue haciendo falta” after the last help — outranks all prior helpsRed (bg-unclaimed)
doneClosed by curator — full green, the only final greenGreen (bg-resolved)
dismissedClosed without resolution — rejected or already done by othersGray (bg-stale)
The rollup exists because “helped once” does not mean “case closed”. A damaged home is worked on over days, by different people, in shifts nobody coordinates centrally. Painting a pin green on the first helped entry caused cases that still needed five more people to stop receiving any. Help moves the pin through amber as it accumulates; green is reserved for an actual curator close. reopened outranks everything: a case where somebody stood there after the last help and said it still is not enough was, under the old model, wearing the color that means handled. The reopened boolean (derived in the database alongside status) is persisted separately so the rollup can catch this.

Activity thread

Anyone can post an update entry, with no account required. Four kinds:
KindSpanish LabelEffect
on_the_wayYo puedo atenderSets status toward claimed; adds to attendeeCount
helpedYa ayudéIncrements helpedCount; two distinct phones closes the case
still_neededSigue haciendo faltaSets reopened = true; outranks all prior helps
not_realEsto no es un caso realCurator review signal; does not close the case on its own
A case never auto-closes on a timer. Two distinct phone numbers posting helped is what allows the sync_work_order_state function to close it. An anonymous helped entry (no phone provided) still shows in the thread and counts toward helpedCount, but it cannot be one of the two distinct phone numbers the closing threshold requires. Anonymity is free everywhere except the one action that takes a case off the map.
Each entry requires a note (3–500 characters) — not because the system needs it, but because a pile of anonymous taps coordinates nothing. The note is addressed to the next person who shows up, not to an administrator. Name and phone are both optional; leaving them blank publishes the entry as “Anónimo”.

Contact fields

exactAddress, contactName, phone, and notes are all public — no reveal gate — since August 15, when the attend-to-reveal gate was removed. They are all optional because the person filling out the form is often a neighbor reporting on behalf of an affected household, not the household itself. The form states out loud that these fields are visible to anyone. A case with no contact fields is still a valid case — the pin and the barrio are what make it findable on the map.

WorkOrderDTO fields

id
string (UUID)
required
Unique identifier for the work order.
category
WorkOrderCategory
required
One of debris_removal, animal_rescue, structural_risk, supplies, other.
description
string
required
Free-text description of the case, e.g. “Escombros bloqueando la entrada de dos casas, se necesita volqueta.”
longitude
number
required
WGS-84 longitude of the case location.
latitude
number
required
WGS-84 latitude of the case location.
neighborhood
string | null
Barrio name, derived from the coordinate by PostGIS. Never written by the application.
status
WorkOrderStatus
required
One of unclaimed, claimed, attended, closed_completed, closed_by_others, closed_rejected. Derived by sync_work_order_state; never written by the application.
attendeeCount
number (integer ≥ 0)
required
Distinct people who said “yo puedo atender”. Several can be attending the same case simultaneously.
helpedCount
number (integer ≥ 0)
required
Distinct people who said “ya ayudé”. Two from two different phone numbers is what closes a case via the database threshold.
reopened
boolean
required
true when someone said “sigue haciendo falta” after the last “ya ayudé”. Derived in the database alongside status. Read through workOrderRollup, which combines it with status and helpedCount to determine what the marker shows.
exactAddress
string | null
Street address or landmark, public since August 15.
contactName
string | null
Name of the person to contact about the case, public since August 15.
phone
string | null
Contact phone number, public since August 15.
notes
string | null
Additional notes for whoever attends, public since August 15.
confirmedAt
string (ISO 8601 datetime with offset)
required
When the case was last touched. Used for freshness labeling (“Publicado hace 2 h”).
createdAt
string (ISO 8601 datetime with offset)
required
When the case was first reported.
published
boolean
required
Whether the work order is visible to the public. Only curators may toggle this.

Creating a work order

Anyone can report a work order — no account required. The contact fields are published on the card, so the form states that where they are typed.
category
WorkOrderCategory
required
One of debris_removal, animal_rescue, structural_risk, supplies, other.
description
string
required
Description of the case. Between 5 and 500 characters.
longitude
number
required
WGS-84 longitude. Must be between -76.2 and -74.8. Out-of-area values are rejected with “Este mapa solo cubre Manizales y Villamaría.”
latitude
number
required
WGS-84 latitude. Must be between 4.6 and 5.6. Same out-of-area message applies.
exactAddress
string
Street address or landmark reference. Maximum 200 characters. Optional.
contactName
string
Name of the person to contact. Maximum 120 characters. Optional.
phone
string
Contact phone number. Digits only, 7–15 characters. Validation message: “Debe ser solo dígitos”. Optional — but a helped entry from a phone-less reporter cannot contribute to the closing threshold.
notes
string
Additional notes for whoever attends. Maximum 500 characters. Optional.
Nothing in the application ever sets status directly. Status is a read-only derived field, computed entirely by the sync_work_order_state Postgres function from the work_order_update thread. Closing is only possible via curator actions (closed_completed, closed_rejected) or via the automatic database threshold (two distinct helped entries from two different phone numbers). Any feature that tries to write a status value directly is a design error — it hands back the single-tap closing power that the append-only thread was built to take away.

Build docs developers (and LLMs) love