Process app feedback marked as 'ai_code' status. Shows a shortlist of the queued feedback items (up to 4) and lets the user pick which one to take, loads all fields and comments as context, and treats admin guidance (admin_notes + internal comments) as authoritative fix directives that steer and can override the raw user request. Checks the item is clear enough to act on (asks for clarification instead of coding a vague request, unless the admin already specified the fix), presents an implementation plan for approval, then routes to the right implementation skill (systematic-debugging, frontend-design, admin-panel-builder, etc.) based on the feedback type. Use when asked to "process ai feedback", "code feedback", "ai-koodaa palaute", or any variation of implementing feedback marked for AI coding.
Process app feedback marked as 'ai_code' status. Shows a shortlist of the queued feedback items (up to 4) and lets the user pick which one to take, loads all fields and comments as context, and treats admin guidance (admin_notes + internal comments) as authoritative fix directives that steer and can override the raw user request. Checks the item is clear enough to act on (asks for clarification instead of coding a vague request, unless the admin already specified the fix), presents an implementation plan for approval, then routes to the right implementation skill (systematic-debugging, frontend-design, admin-panel-builder, etc.) based on the feedback type. Use when asked to "process ai feedback", "code feedback", "ai-koodaa palaute", or any variation of implementing feedback marked for AI coding.
AI Feedback Coder
Automates coding feedback items marked as ai_code in public.app_feedback.
Workflow
1. Query the candidate shortlist
Use mcp__plugin_supabase_supabase__execute_sql with project ID iryqgmjauybluwnqhxbg.
Fetch a short list (not one row) plus the total count, so the user can choose
which item to take — not just the front of the queue:
SELECT id, feedback_type, system_id, subject,
left(message, 140) AS preview, satisfaction_rating, created_at
FROM public.app_feedback
WHERE status ='ai_code'ORDERBY created_at ASC
LIMIT 4;
SELECTcount() public.app_feedback status ;
*
FROM
WHERE
=
'ai_code'
ORDER BY created_at ASC = oldest first (front of the FIFO queue). The oldest is
the default pick, but the user may take any of the shown items.
2. If none found
Report "Ei ai_code-palautteita jonossa" and stop.
3. Let the user pick which feedback to take
MANDATORY — never silently grab the first row. Present the shortlist with
AskUserQuestion (single-select) and use the preview field so the user can
compare the candidates side by side:
One option per feedback (up to 4). Label = [feedback_type] + subject (or
message) truncated to ~40 chars. Preview = a monospace block with
feedback_type, system_id, created_at (date), satisfaction_rating (as
★ if present), and the message/preview text.
The oldest (front of queue) must be the first option so Enter takes it.
Add a final "Lopeta" option.
Handle the response:
A feedback option → that row becomes the active feedback; continue to step 4.
"Lopeta" → stop.
Even if only one candidate exists, still show it (single option + "Lopeta") so
the user confirms the target before any work begins.
4. Fetch the full record + comments
The shortlist query returned only summary columns. Re-select every field for the
chosen id, and load the comments (they often carry the real detail):
SELECT*FROM public.app_feedback WHERE id ='<id>';
SELECT*FROM public.feedback_comments
WHERE feedback_id ='<id>'ORDERBY created_at ASC;
admin_notes (field on app_feedback) and any comment with is_internal = true
are admin directives — the admin's own instructions on how to fix the item.
Treat them as authoritative (see step 5's "Admin directives" block). Regular
non-internal comments are usually from the reporter; internal ones are admin.
5. Build context block
Assemble all feedback fields into a structured context:
id, system_id, feedback_type, subject, message
satisfaction_rating, email, allow_contact
status, admin_notes, promoted_idea_id
page_url, user_agent, browser_history
kipina_id, created_at
All comments (message, is_internal, created_at)
The system_id field tells which app the feedback concerns — see src/lib/systems.ts for the app registry.
Admin directives (authoritative)
Extract a separate Admin-ohjeet group from these two sources and treat it as
the admin steering the fix — the admin uses these fields to tell the AI how to
implement, not just what the reporter said:
admin_notes — the admin's implementation instructions. These are
frequently concrete and directive (real examples: "Tee ilman taustaa.
Ikonityyppinen.", "Vasen yläkulma. Kun kipinäkortti on pienennetty, näytä
pieni ikoni…").
Internal comments (is_internal = true) — admin-only notes, often a
threaded refinement of the instruction.
Priority rule: admin directives outrank the raw user message. When they add
detail, follow it. When they conflict with the reporter's literal request,
follow the admin and flag the conflict in the plan (step 7). If there are no
admin directives, proceed from the user message as before.
6. Clarity gate — is the feedback actionable?
MANDATORY before planning or routing. Do NOT start coding on a vague item.
Judge whether the feedback is specific enough to implement correctly. Treat it
as UNCLEAR when any of these hold:
The request is generic ("ei toimi", "korjaa tämä", "huono") with no specifics.
The target is ambiguous — you cannot tell which page/component/flow from the
message + page_url + comments.
The desired outcome has multiple reasonable interpretations.
For a bug, reproduction cannot be inferred.
Admin directives resolve ambiguity. Judge clarity from the combined
picture: user message + admin directives (step 5). If admin_notes or an
internal comment already names the target and the intended fix, treat the item
as CLEAR and follow the admin's instruction — even when the raw user message is
vague. Only fall through to the UNCLEAR path when both the user message and the
admin directives are insufficient.
If the feedback IS clear, continue to step 7.
If UNCLEAR → use AskUserQuestion to resolve it BEFORE any plan. Ask one crisp,
targeted question (what exactly is broken, on which page, what is the expected
result) — not a barrage. Offer:
"Tarkenna" (Other / free text) → user supplies the missing detail → re-run
this gate with the new information.
"Ohita" → mark the feedback read (see step 9's UPDATE, status read) so a
human can triage it, then return to the picker (step 1).
"Koodaa silti" → the user accepts a best-effort interpretation; proceed, but
state your assumptions explicitly in the plan (step 7) and in the audit
comment (step 10).
Never guess silently and start editing files — asking one question is cheap;
shipping the wrong fix is not.
7. Announce and present plan
Tell the user:
Palaute: [subject or message truncated to ~80 chars]
Tyyppi: [feedback_type] | Sovellus: [system_id] | Jaljella: N kpl
Admin-ohje: [admin_notes / internal-kommentti sanatarkasti — TAI "ei admin-ohjetta"]
Suunnitelma:
[Konkreettinen askel 1 — esim. "Muokkaa ComponentX.tsx: lisaa null-tarkistus"]
[Konkreettinen askel 2]
...
Tiedostot joihin koskee: file1.tsx, file2.ts
The Admin-ohje line is mandatory: quote the admin directive verbatim (or state
there is none). The plan steps must implement what the admin directed — if the
admin's instruction and the reporter's literal request differ, follow the admin
and add a short note in the plan (e.g. "Admin ohjaa X:ään, ei käyttäjän
pyytämään Y:hyn").
MANDATORY — always present this plan and wait for user confirmation using the AskUserQuestion tool before proceeding.
Use AskUserQuestion with these options:
"Jatka" (description: "Toteuta suunnitelma sellaisenaan")
"Anna lisäohjetta" (description: "Muokkaa suunnitelmaa ennen toteutusta")
"Peruuta" (description: "Ohita tämä palaute, merkitse luetuksi")
Handle the response:
Jatka → proceed to step 8 (route to implementation)
Anna lisäohjetta → user types instructions via "Other" → adjust plan and re-present with AskUserQuestion again
Peruuta → mark feedback as read instead of fixed and stop
Other (free text) → treat as instructions, adjust plan and re-present
To build a good plan, use the Explore agent or Grep/Glob to find the relevant files before presenting. The plan should be concrete enough that the user can judge if the approach is correct.
8. Route to the right implementation skill
After user approves the plan, invoke the appropriate skill(s) directly based on what the feedback requires. Do NOT delegate to using-superpowers — route directly.
Routing table
Feedback concerns
Invoke skill
Context to pass
Bug / unexpected behavior
systematic-debugging
Error description, reproduction steps, page_url
UI / layout / component issue
frontend-design
Component name, expected vs actual behavior
Admin panel issue
admin-panel-builder
Admin page, tab, what's broken/missing
Database / RLS / migration needed
supabase-migration-writer
Table, operation, expected behavior
Edge Function issue
edge-function-generator
Function name, error, expected behavior
AI feature / prompt issue
ai-prompt-manager
Feature name, prompt, expected behavior
Idea Machina specific
idea-machina
Evolution stage, component, issue
Practice / gamification
practice-gamification
Practice type, scheduling, completion
New feature (general)
brainstorming first, then implementation skill
Full feedback context + plan
Type errors / Supabase types
supabase-typing-architect
File, type error, schema
i18n / translation
language-specialist
Missing key, language, component
Performance
performance-auditor
Slow query, component, metric
Multiple skills may apply. For example, a feature request may need brainstorming → supabase-migration-writer → frontend-design. Run them in sequence.
If the feedback doesn't clearly match any skill, use code-guru for general implementation guidance.
9. Update feedback status
MANDATORY — always run after implementation, even if implementation was partial:
UPDATE public.app_feedback SET status ='fixed'WHERE id ='<id>';
10. Add admin comment documenting what was done
MANDATORY — write a concise Finnish summary of every change made (files modified, features added, bugs fixed). This is the audit trail.
feedback_comments.user_id is uuid and NOT NULL, so the author must be a
real uuid. Use the oldest auth user (an admin) — do NOT cast to text or fall
back to a text literal (the column is uuid; a text expression errors with
42804: column "user_id" is of type uuid but expression is of type text). The
feedback's own user_id is often NULL, so it is not a usable fallback.
INSERT INTO public.feedback_comments (feedback_id, user_id, message, is_internal)
VALUES (
'<id>',
(SELECT id FROM auth.users ORDERBY created_at ASC LIMIT 1),
'AI-toteutettu: <1-3 lauseen yhteenveto tehdyistä muutoksista, esim. "Korjattu sidebar-komponentin renderöintiongelma. Muokattu sidebar.tsx: lisätty null-tarkistus props-arvoille.">',
true
);
The comment message must include:
What was changed (file names or component names)
Why (link back to the feedback problem)
If an admin directive steered the work, note it (e.g. "admin-ohjeen mukaan
ikoni vasempaan yläkulmaan") — and, if the admin instruction overrode the
reporter's literal request, say so
Keep it under 300 characters
11. Report and continue
Report the final count, then use AskUserQuestion to offer continuing:
"Seuraava" (description: "Hae ja käsittele seuraava ai_code-palaute") — this must be the first option so Enter accepts it
"Lopeta" (description: "Lopeta palautekierros")
If user picks "Seuraava", go back to step 1. If "Lopeta", stop.