anky2002 commited on
Commit
3bfdfdc
·
verified ·
1 Parent(s): b89b876

feat: Add job blacklist (hide companies/roles you don't want to see)

Browse files
Files changed (1) hide show
  1. backend/app/api/routes/blacklist.py +84 -0
backend/app/api/routes/blacklist.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Job blacklist - hide specific companies or role keywords from search results.
3
+ """
4
+ import uuid
5
+ from datetime import datetime
6
+
7
+ from fastapi import APIRouter, HTTPException, status
8
+ from pydantic import BaseModel
9
+ from sqlalchemy import DateTime, String, func, select
10
+ from sqlalchemy.dialects.postgresql import UUID as PGUUID
11
+ from sqlalchemy.orm import Mapped, mapped_column
12
+
13
+ from app.api.deps import CurrentUser, DBSession
14
+ from app.core.database import Base
15
+
16
+ router = APIRouter(prefix="/blacklist", tags=["blacklist"])
17
+
18
+
19
+ class BlacklistEntry(Base):
20
+ """Companies or keywords user wants to hide from results."""
21
+ __tablename__ = "blacklist_entries"
22
+
23
+ id: Mapped[uuid.UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
24
+ user_id: Mapped[uuid.UUID] = mapped_column(PGUUID(as_uuid=True), nullable=False, index=True)
25
+ entry_type: Mapped[str] = mapped_column(String(20), nullable=False) # company, keyword, domain
26
+ value: Mapped[str] = mapped_column(String(256), nullable=False)
27
+ reason: Mapped[str | None] = mapped_column(String(256), nullable=True)
28
+ created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
29
+
30
+
31
+ class BlacklistCreate(BaseModel):
32
+ entry_type: str # company, keyword, domain
33
+ value: str
34
+ reason: str | None = None
35
+
36
+
37
+ class BlacklistResponse(BaseModel):
38
+ id: str
39
+ entry_type: str
40
+ value: str
41
+ reason: str | None
42
+ created_at: datetime
43
+
44
+ class Config:
45
+ from_attributes = True
46
+
47
+
48
+ @router.get("", response_model=list[BlacklistResponse])
49
+ async def list_blacklist(db: DBSession, user: CurrentUser):
50
+ """Get user's blacklist entries."""
51
+ result = await db.execute(
52
+ select(BlacklistEntry).where(BlacklistEntry.user_id == user.id).order_by(BlacklistEntry.created_at.desc())
53
+ )
54
+ return [
55
+ BlacklistResponse(id=str(e.id), entry_type=e.entry_type, value=e.value, reason=e.reason, created_at=e.created_at)
56
+ for e in result.scalars().all()
57
+ ]
58
+
59
+
60
+ @router.post("", response_model=BlacklistResponse, status_code=status.HTTP_201_CREATED)
61
+ async def add_to_blacklist(data: BlacklistCreate, db: DBSession, user: CurrentUser):
62
+ """Add a company, keyword, or domain to blacklist."""
63
+ if data.entry_type not in ("company", "keyword", "domain"):
64
+ raise HTTPException(status_code=400, detail="entry_type must be: company, keyword, or domain")
65
+
66
+ entry = BlacklistEntry(
67
+ user_id=user.id, entry_type=data.entry_type, value=data.value.strip(), reason=data.reason
68
+ )
69
+ db.add(entry)
70
+ await db.flush()
71
+ await db.refresh(entry)
72
+ return BlacklistResponse(id=str(entry.id), entry_type=entry.entry_type, value=entry.value, reason=entry.reason, created_at=entry.created_at)
73
+
74
+
75
+ @router.delete("/{entry_id}", status_code=status.HTTP_204_NO_CONTENT)
76
+ async def remove_from_blacklist(entry_id: uuid.UUID, db: DBSession, user: CurrentUser):
77
+ """Remove an entry from blacklist."""
78
+ result = await db.execute(
79
+ select(BlacklistEntry).where(BlacklistEntry.id == entry_id, BlacklistEntry.user_id == user.id)
80
+ )
81
+ entry = result.scalar_one_or_none()
82
+ if not entry:
83
+ raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Entry not found")
84
+ await db.delete(entry)