mirror of
https://github.com/renee-png/acmcc.git
synced 2026-06-21 09:50:01 +00:00
Hostinger Reach integration UI + ARC Buildium matching, drop Mailchimp
- HostingerReachPage (replaces MailchimpPage): connect Reach via reach-connection, per-association segment sync via reach-sync - ARC Applications: Buildium import review/matching updates - buildium-import-stage/apply: latest staging + apply changes (already deployed to Supabase) - migrations: hostinger_reach_integration + arc_finalized_lock service role (already applied to live DB) - CI: note that deployment is VPS-side polling (auto-deploy.sh cron) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -260,10 +260,7 @@ Deno.serve(async (req) => {
|
||||
const files: Array<{ id: string; name: string }> = Array.isArray(p._arc_files) ? p._arc_files : [];
|
||||
const buildiumAssocId: string | null = p._arc_buildium_association_id || null;
|
||||
const buildiumArcId: string | null = p.buildium_arc_request_id || null;
|
||||
const decisionNotes: string | null = p.decision_notes || null;
|
||||
const reviewDate: string | null = p.review_date || null;
|
||||
const deciderName: string | null = p._arc_decider_name || null;
|
||||
const deciderDate: string | null = p._arc_decider_date || null;
|
||||
|
||||
const clean = stripPrivate(p);
|
||||
|
||||
@@ -282,27 +279,32 @@ Deno.serve(async (req) => {
|
||||
appId = ins.id;
|
||||
}
|
||||
|
||||
// Seed a system comment with the Buildium decision (since comments/voters aren't exposed via API)
|
||||
if (appId && (decisionNotes || deciderName)) {
|
||||
const { data: existingComment } = await supabase
|
||||
.from("arc_application_comments")
|
||||
.select("id")
|
||||
.eq("application_id", appId)
|
||||
// Buildium's API exposes no comment threads or per-member votes — only the final decision
|
||||
// and who recorded it. Surface that decision as a recorded vote in the Committee Review
|
||||
// (entity_votes is what the ARC review UI reads). The decision text itself already lives in
|
||||
// arc_applications.decision_notes. Idempotent: re-syncing replaces the prior Buildium vote.
|
||||
const decisionRaw: string = String(p._arc_decision || "").toLowerCase();
|
||||
const voteDir: "approve" | "deny" | null = decisionRaw.includes("approve")
|
||||
? "approve"
|
||||
: (decisionRaw.includes("den") || decisionRaw.includes("reject") ? "deny" : null);
|
||||
if (appId && voteDir) {
|
||||
const voterName = `${deciderName || "Buildium"} (Buildium)`;
|
||||
await supabase
|
||||
.from("entity_votes")
|
||||
.delete()
|
||||
.eq("entity_type", "arc_application")
|
||||
.eq("entity_id", appId)
|
||||
.is("user_id", null)
|
||||
.ilike("comment", "%[Imported from Buildium]%")
|
||||
.maybeSingle();
|
||||
if (!existingComment) {
|
||||
const seed =
|
||||
`[Imported from Buildium]\n` +
|
||||
(deciderName ? `Decision by: ${deciderName}${deciderDate ? ` on ${deciderDate}` : ""}\n` : "") +
|
||||
(reviewDate && !deciderDate ? `Decision date: ${reviewDate}\n` : "") +
|
||||
(decisionNotes ? `Decision notes: ${decisionNotes}` : "");
|
||||
await supabase.from("arc_application_comments").insert({
|
||||
application_id: appId,
|
||||
user_id: null,
|
||||
comment: seed.trim(),
|
||||
});
|
||||
}
|
||||
.ilike("voter_name", "% (Buildium)");
|
||||
const { error: voteErr } = await supabase.from("entity_votes").insert({
|
||||
entity_type: "arc_application",
|
||||
entity_id: appId,
|
||||
vote: voteDir,
|
||||
user_id: null,
|
||||
voter_name: voterName,
|
||||
recorded_by: null,
|
||||
});
|
||||
if (voteErr) console.warn(`ARC vote record failed for ${appId}: ${voteErr.message}`);
|
||||
}
|
||||
|
||||
// Download attached files from Buildium and upload into the arc-files bucket
|
||||
|
||||
Reference in New Issue
Block a user