-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add filters on getAllOrgs #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9790c99
1a1d9d2
3e5fe12
aa1c2eb
a198f37
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| import { z } from 'zod' | ||
|
|
||
| const ongCategoryEnum = z.enum([ | ||
| 'animais', | ||
| 'meioAmbiente', | ||
| 'educacao', | ||
| 'saude', | ||
| 'direitosHumanos', | ||
| 'combateAFome', | ||
| 'criancasEAdolescentes', | ||
| 'idosos', | ||
| 'pessoasComDeficiencia', | ||
| 'moradoresDeRua', | ||
| 'igualdadeDeGenero', | ||
| 'refugiadosEImigrantes', | ||
| 'protecaoAnimal', | ||
| 'desenvolvimentoComunitario', | ||
| 'culturaEArte', | ||
| 'esporteEInclusao', | ||
| 'voluntariadoEDoacoes', | ||
| 'tecnologiaSocial', | ||
| 'direitosDasMulheres', | ||
| 'outros' | ||
| ]) | ||
|
|
||
| export const getAllOrganizationsQuerySchema = z.object({ | ||
| name: z.string().optional(), | ||
| ong_type: ongCategoryEnum.optional() | ||
| }) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| import { Prisma } from '@prisma-generated' | ||
| import { OngCategory, Prisma } from '@prisma-generated' | ||
| import { randomUUID } from 'crypto' | ||
| import { | ||
| OrganizationInterface, | ||
|
|
@@ -65,8 +65,14 @@ export class OrganizationsRepository implements OrganizationInterface { | |
| }) | ||
| } | ||
|
|
||
| getAllOrganizations = async () => { | ||
| getAllOrganizations = async (filters?: { name?: string; ong_type?: OngCategory }) => { | ||
| return await prisma.organization.findMany({ | ||
| where: { | ||
| organization_profile: { | ||
| ...(filters?.name && { name: { contains: filters.name, mode: 'insensitive' } }), | ||
| ...(filters?.ong_type && { ong_type: filters.ong_type }) | ||
| } | ||
| }, | ||
|
Comment on lines
+70
to
+75
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify optional relation cardinality and current repository filter shape.
rg -n "organization_profile OrganizationProfile\\?" prisma/schema/account.prisma -C3
rg -n "getAllOrganizations\\s*=\\s*async" src/adapters/outbound/prisma/repositories/organization-repository.ts -A30Repository: ifsp-projects/backend Length of output: 1177 🏁 Script executed: #!/bin/bash
# 1. Check if organization_profile can be null/missing (relation cardinality)
rg "organization_profile" prisma/schema/account.prisma -B5 -A5
# 2. Check if there are tests for getAllOrganizations
fd ".*test.*" -e ts -e js | xargs grep -l "getAllOrganizations" 2>/dev/null | head -5
# 3. Look for how organizations are created/seeded
fd ".*seed.*" -e ts -e js | head -5
# 4. Check for any migration or validation logic around organization_profile
rg "organization_profile" src/ -l | head -10Repository: ifsp-projects/backend Length of output: 1197 🏁 Script executed: #!/bin/bash
# 1. Check the interface/port definition
cat src/core/domain/ports/repositories/organization-repository.ts
# 2. Look for test files
fd "getAllOrganizations|organization.*test" . -e ts -e js
# 3. Check how this method is used in controllers
rg "getAllOrganizations" src/ -B2 -A2Repository: ifsp-projects/backend Length of output: 9161 🏁 Script executed: #!/bin/bash
# 1. Check the actual usage in the controller to see what return type is expected
cat src/adapters/inbound/http/controllers/organizations/get-all-organizations/index.ts
# 2. Look for any test files to understand intended behavior
find . -type f -name "*.test.*" -o -name "*.spec.*" | xargs grep -l "getAllOrganizations" 2>/dev/null | head -5
# 3. Check if there's any documentation or comments about the relation
rg "organization_profile" src/adapters/outbound/prisma/repositories/organization-repository.ts -B3 -A10Repository: ifsp-projects/backend Length of output: 2745 🏁 Script executed: #!/bin/bash
# Verify if organizations can actually exist without profiles
# Check creation patterns and any data about orgs without profiles
# 1. Look at how organizations are typically created
rg "prisma.organization.create|Organization.create" src/ -B3 -A5
# 2. Check if there are migrations that might shed light on this
find . -name "*.sql" -o -path "*/migrations/*" 2>/dev/null | head -10
# 3. Check the organizational structure to understand the domain
cat src/core/domain/ports/repositories/organization-profile-repository.ts | head -30
# 4. Look for any explicit checks or comments about organization without profile
rg "organization.*profile.*null|organization.*without.*profile" src/ -iRepository: ifsp-projects/backend Length of output: 3141 🏁 Script executed: #!/bin/bash
# Critical check: Does Prisma's empty object filter actually exclude organizations without profiles?
# Let's look at any documentation or tests that show the intended behavior
# 1. Check the return type expectations
rg "getAllOrganizations.*Promise" src/core -A1
# 2. Look for any seeders or fixtures that might show the expected data state
find . -name "*seed*" -o -name "*fixture*" | grep -E "\.(ts|js)$"
# 3. Check if there's any explicit statement about org-profile requirement
rg "organization_profile.*required|must.*profile|without.*profile" src/ -i
# 4. Check the interface return type - it returns Organization[], not OrganizationWithProfileInclude
# This is a key detail. Let's verify what Organization vs OrganizationWithProfileInclude is
rg "type Organization[^P]|interface Organization" src/ -B2 -A5Repository: ifsp-projects/backend Length of output: 2793 🏁 Script executed: #!/bin/bash
# Check the actual return type mismatch and Prisma behavior documentation
# The critical issue: does where: { organization_profile: {} } exclude orgs without profiles?
# 1. Verify the type mismatch - interface says Organization[], implementation includes profile
rg "getAllOrganizations.*=" src/adapters/outbound/prisma/repositories/organization-repository.ts -A25 | grep -E "return|include|where"
# 2. Check if there's any documentation or comments about Prisma relation filtering
rg "organization_profile.*where|where.*organization_profile" src/ -B2 -A2
# 3. Look for any GitHub issues or comments about this
find . -name "*.md" -o -name "*.txt" | xargs grep -i "organization.*profile.*filter" 2>/dev/null
# 4. Check the return type signature consistency
cat > /tmp/check_types.ts << 'EOF'
// The interface definition says:
// getAllOrganizations: (...) => Promise<Organization[]>
// But the implementation does:
// return await prisma.organization.findMany({
// where: { organization_profile: { ... } },
// include: { organization_profile: true }
// })
// This should return OrganizationWithProfileInclude[] or Organization[]?
// Type mismatch suggests the implementation is wrong OR the interface is wrong
EOF
# 5. Verify: when organization_profile is in where clause with empty object,
# does Prisma exclude orgs without profile? This is the core issue.
# From Prisma docs: where relation: {} on optional relation DOES match records WITH the relation
# But to get ALL records (with or without), relation filter should not be in where at all
echo "ANALYSIS: In Prisma, where: { optional_relation: {...} } only matches records WITH that relation"
echo "Therefore, the current code WILL exclude organizations without profiles"Repository: ifsp-projects/backend Length of output: 389 🏁 Script executed: #!/bin/bash
# Check if the return type is actually correct or if there's a mismatch
# The interface says Organization[] but implementation returns with includes
# 1. Look at what getAllOrganizations actually returns in practice
rg "getAllOrganizations" src/core/use-cases/organizations/get-all-organizations/ -A10
# 2. Check how the response is used by the controller
rg "useCase.execute" src/adapters/inbound/http/controllers/organizations/get-all-organizations/ -B3 -A5
# 3. Check if Organization type includes organization_profile or not
# This will tell us if the implementation matches the interface
rg "export.*Organization[^P].*=|type Organization[^P]" src/ -l
# 4. Let's check the generated Prisma types
find . -path "*prisma*" -name "*.ts" | grep -i "index\|types" | head -5Repository: ifsp-projects/backend Length of output: 3621 🏁 Script executed: #!/bin/bash
# Final verification: confirm Prisma's behavior with empty relation objects in where clauses
# and verify if this impacts actual behavior
# 1. Check if organization_profile is ACTUALLY optional or if it's always created with organization
rg "organization_profile" prisma/schema/account.prisma -B5 -A5 | grep -E "model Organization|model OrganizationProfile|organization_profile"
# 2. Look at the full getAllOrganizations implementation once more for precision
sed -n '68,80p' src/adapters/outbound/prisma/repositories/organization-repository.ts
# 3. Check if any tests actually call getAllOrganizations without filters
find . -type f \( -name "*.test.ts" -o -name "*.spec.ts" \) -exec grep -l "getAllOrganizations" {} \;Repository: ifsp-projects/backend Length of output: 715 Filtering always requires When no filters are provided to Conditionally apply the Suggested fix getAllOrganizations = async (filters?: { name?: string; ong_type?: OngCategory }) => {
+ const name = filters?.name?.trim()
+ const hasProfileFilters = Boolean(name || filters?.ong_type)
+
return await prisma.organization.findMany({
- where: {
- organization_profile: {
- ...(filters?.name && { name: { contains: filters.name, mode: 'insensitive' } }),
- ...(filters?.ong_type && { ong_type: filters.ong_type })
- }
- },
+ where: hasProfileFilters
+ ? {
+ organization_profile: {
+ is: {
+ ...(name && { name: { contains: name, mode: 'insensitive' } }),
+ ...(filters?.ong_type && { ong_type: filters.ong_type })
+ }
+ }
+ }
+ : undefined,
include: {
organization_profile: true
}
})
}🤖 Prompt for AI Agents |
||
| include: { | ||
| organization_profile: true | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard the Prisma config rename to prevent avoidable CI failures.
Line 44 fails the job if
prisma.config.tsis absent (or already renamed). That makes the build step brittle.🛠️ Suggested hardening
- name: Run Build run: | - mv prisma.config.ts prisma.config.ts.bak + if [ -f prisma.config.ts ]; then + mv prisma.config.ts prisma.config.ts.bak + fi pnpm run build📝 Committable suggestion
🤖 Prompt for AI Agents