# Upsert perfil al hacer login (CRITICAL)
mutation UpsertMyProfile(
$email: String!,
$displayName: String,
$avatarUrl: String
) @auth(level: USER) {
user_upsert(data: {
uid_expr: "auth.uid",
email: $email,
displayName: $displayName,
avatarUrl: $avatarUrl
})
}
# SDR: crear lead en su agencia
mutation CreateLead(
$agencyId: UUID!,
$email: String!,
$firstName: String!,
$lastName: String,
$company: String,
$campaignId: UUID
) @auth(level: USER) @transaction {
# Verificar que el user pertenece a la agencia
query @redact {
agencyMember(key: {
user: { uid_expr: "auth.uid" }
}) @check(expr: "this != null",
message: "Not a member") {
agency { id
@check(expr: "this == request.variables.agencyId",
message: "Agency mismatch")
}
}
}
lead_insert(data: {
agency: { id: $agencyId },
email: $email,
firstName: $firstName,
lastName: $lastName,
company: $company,
campaign: { id: $campaignId },
assignedTo: { uid_expr: "auth.uid" }
})
}
# Mover lead en el pipeline + registrar actividad
mutation UpdateLeadStatus(
$leadId: UUID!,
$status: LeadStatus!,
$activityNote: String
) @auth(level: USER) @transaction {
# Solo el SDR asignado o MANAGER/OWNER
query @redact {
lead(id: $leadId)
@check(expr: "this != null", message: "Lead not found") {
assignedTo { uid
@check(
expr: "this == auth.uid || auth.token.role in ['MANAGER','OWNER']",
message: "Access denied"
)
}
}
}
lead_update(id: $leadId, data: {
status: $status,
updatedAt_expr: "request.time"
})
leadActivity_insert(data: {
lead: { id: $leadId },
author: { uid_expr: "auth.uid" },
type: NOTE,
note: $activityNote
})
}
# AΓ±adir actividad (trigger Cloud Function)
mutation LogActivity(
$leadId: UUID!,
$type: ActivityType!,
$note: String,
$outcome: String
) @auth(level: USER) {
leadActivity_insert(data: {
lead: { id: $leadId },
author: { uid_expr: "auth.uid" },
type: $type,
note: $note,
outcome: $outcome
})
}
# OWNER: crear agencia + asignarse OWNER
mutation CreateAgency(
$name: String!,
$slug: String!
) @auth(level: USER) @transaction {
agency_insert(data: {
name: $name,
slug: $slug
})
agencyMember_insert(data: {
user: { uid_expr: "auth.uid" },
agency: { id_expr: "response.agency_insert.id" },
role: OWNER
})
}
# OWNER: invitar miembro
mutation InviteMember(
$agencyId: UUID!,
$userUid: String!,
$role: MemberRole!
) @auth(level: USER) @transaction {
# Solo OWNER puede invitar
query @redact {
agencyMember(key: {
user: { uid_expr: "auth.uid" }
}) {
role @check(
expr: "this == 'OWNER'",
message: "Only OWNER can invite"
)
}
}
agencyMember_upsert(data: {
user: { uid: $userUid },
agency: { id: $agencyId },
role: $role
})
}
# Asignar lead a SDR (MANAGER+)
mutation AssignLead(
$leadId: UUID!,
$sdrUid: String!
) @auth(level: USER) @transaction {
query @redact {
agencyMember(key: {
user: { uid_expr: "auth.uid" }
}) {
role @check(
expr: "this in ['OWNER','MANAGER']",
message: "Managers only"
)
}
}
lead_update(id: $leadId, data: {
assignedTo: { uid: $sdrUid }
})
}
# Tags β crear y etiquetar lead
mutation CreateTag(
$agencyId: UUID!,
$name: String!,
$color: String
) @auth(level: USER) {
tag_insert(data: {
agency: { id: $agencyId },
name: $name,
color: $color
})
}
mutation TagLead(
$leadId: UUID!,
$tagId: UUID!
) @auth(level: USER) {
leadTag_upsert(data: {
lead: { id: $leadId },
tag: { id: $tagId }
})
}
mutation UntagLead(
$leadId: UUID!,
$tagId: UUID!
) @auth(level: USER) {
leadTag_delete(key: {
lead: { id: $leadId },
tag: { id: $tagId }
})
}