""" Database models for the Election Process Assistant """ from app import db from datetime import datetime class ElectionProcess(db.Model): __tablename__ = 'election_process' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(200), nullable=False, unique=True) description = db.Column(db.Text, nullable=False) estimated_duration = db.Column(db.String(100)) difficulty_level = db.Column(db.String(20)) created_at = db.Column(db.DateTime, default=datetime.utcnow) steps = db.relationship('ProcessStep', backref='process', cascade='all, delete-orphan') timeline_events = db.relationship('TimelineEvent', backref='process', cascade='all, delete-orphan') def to_dict(self): return { 'id': self.id, 'name': self.name, 'description': self.description, 'estimated_duration': self.estimated_duration, 'difficulty_level': self.difficulty_level, 'steps': [s.to_dict() for s in self.steps], 'timeline_events': [e.to_dict() for e in self.timeline_events], } class ProcessStep(db.Model): __tablename__ = 'process_step' id = db.Column(db.Integer, primary_key=True) process_id = db.Column(db.Integer, db.ForeignKey('election_process.id'), nullable=False) step_number = db.Column(db.Integer, nullable=False) title = db.Column(db.String(200), nullable=False) description = db.Column(db.Text, nullable=False) key_points = db.Column(db.JSON, default=list) resources = db.Column(db.JSON, default=list) estimated_time = db.Column(db.String(100)) def to_dict(self): return { 'id': self.id, 'step_number': self.step_number, 'title': self.title, 'description': self.description, 'key_points': self.key_points, 'resources': self.resources, 'estimated_time': self.estimated_time, } class TimelineEvent(db.Model): __tablename__ = 'timeline_event' id = db.Column(db.Integer, primary_key=True) process_id = db.Column(db.Integer, db.ForeignKey('election_process.id'), nullable=False) event_date = db.Column(db.DateTime, nullable=False) title = db.Column(db.String(200), nullable=False) description = db.Column(db.Text) importance = db.Column(db.String(20)) category = db.Column(db.String(100)) status = db.Column(db.String(50), default='pending') details = db.Column(db.JSON, default=dict) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) def to_dict(self): return { 'id': self.id, 'event_date': self.event_date.isoformat(), 'title': self.title, 'description': self.description, 'importance': self.importance, 'category': self.category, 'status': self.status, 'details': self.details, 'updated_at': self.updated_at.isoformat() if self.updated_at else None, } class FAQ(db.Model): __tablename__ = 'faq' id = db.Column(db.Integer, primary_key=True) question = db.Column(db.String(500), nullable=False) answer = db.Column(db.Text, nullable=False) category = db.Column(db.String(100)) order = db.Column(db.Integer) created_at = db.Column(db.DateTime, default=datetime.utcnow) def to_dict(self): return { 'id': self.id, 'question': self.question, 'answer': self.answer, 'category': self.category, } # ── Seed data ──────────────────────────────────────────────── def seed_election_data(): """Populate the database with India 2026 General Election data.""" if ElectionProcess.query.first(): return process = ElectionProcess( name='India 2026 General Election', description=( 'Interactive guide to the 2026 Indian General Election. ' 'Understand the complete election process — from voter registration ' 'to counting day — conducted by the Election Commission of India (ECI).' ), estimated_duration='3 months (May – July 2026)', difficulty_level='Medium', ) db.session.add(process) db.session.flush() # ── Timeline events ────────────────────────────────────── events = [ TimelineEvent( process_id=process.id, event_date=datetime(2026, 5, 1), title='ECI Notification — Election Announced', description='The Election Commission of India issues the official notification announcing the 2026 General Election schedule, Model Code of Conduct comes into effect.', importance='critical', category='Notification', status='pending', details={'phase': 'notification', 'mcc_active': True}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 5, 5), title='Model Code of Conduct Begins', description='All political parties and candidates must adhere to the Model Code of Conduct. No new government schemes or announcements permitted.', importance='high', category='Regulation', status='pending', details={'applies_to': 'all parties and government machinery'}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 5, 8), title='Filing of Nominations Opens', description='Candidates can file their nomination papers with the Returning Officer. Candidates must submit an affidavit with personal and financial details.', importance='high', category='Nominations', status='pending', details={'documents_required': ['Form 26', 'Affidavit', 'Security Deposit']}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 5, 15), title='Last Date for Filing Nominations', description='Final day for candidates to submit nomination papers for Phase 1 constituencies.', importance='critical', category='Nominations', status='pending', details={'deadline': True}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 5, 17), title='Scrutiny of Nominations', description='The Returning Officer examines all nomination papers for validity — verifies qualifications, signatures, and supporting documents.', importance='high', category='Nominations', status='pending', details={'officer': 'Returning Officer'}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 5, 20), title='Last Date for Withdrawal of Candidature', description='Candidates may withdraw their nominations by this date. Final list of contesting candidates published.', importance='high', category='Nominations', status='pending', details={'final_list_published': True}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 5, 22), title='Allotment of Election Symbols', description='ECI allots election symbols to all contesting candidates. Recognised party candidates get their reserved symbols.', importance='medium', category='Preparation', status='pending', details={'symbols_by': 'ECI'}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 5, 25), title='Campaign Period Begins in Full Swing', description='Intensive campaigning by candidates — rallies, roadshows, door-to-door campaigns, media advertisements, and social media outreach.', importance='high', category='Campaign', status='pending', details={'methods': ['Rallies', 'Roadshows', 'Social Media', 'Print/TV Ads']}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 6, 5), title='Campaign Silence Period — Phase 1', description='Campaigning must stop 48 hours before polling. No public meetings, processions, or advertisements allowed.', importance='critical', category='Campaign', status='pending', details={'hours_before_poll': 48}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 6, 7), title='Phase 1 — Polling Day', description='Voting in Phase 1 constituencies using EVMs (Electronic Voting Machines) with VVPAT verification. Polling from 7 AM to 6 PM.', importance='critical', category='Polling', status='pending', details={'phase': 1, 'method': 'EVM + VVPAT', 'timing': '7 AM – 6 PM'}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 6, 14), title='Phase 2 — Polling Day', description='Voting in Phase 2 constituencies. Security forces deployed in sensitive areas. Booth-level monitoring by ECI observers.', importance='critical', category='Polling', status='pending', details={'phase': 2}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 6, 21), title='Phase 3 — Polling Day', description='Voting in Phase 3 constituencies across multiple states. Special provisions for differently-abled and elderly voters.', importance='critical', category='Polling', status='pending', details={'phase': 3}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 6, 28), title='Phase 4 — Polling Day', description='Voting in Phase 4 constituencies. Includes heartland states and major urban centres.', importance='critical', category='Polling', status='pending', details={'phase': 4}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 7, 5), title='Phase 5 — Polling Day', description='Voting in Phase 5 constituencies covering northern and eastern states.', importance='critical', category='Polling', status='pending', details={'phase': 5}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 7, 12), title='Phase 6 — Polling Day', description='Voting in Phase 6 constituencies. High voter turnout typically observed in rural areas.', importance='critical', category='Polling', status='pending', details={'phase': 6}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 7, 19), title='Phase 7 — Final Polling Day', description='Last phase of voting. Remaining constituencies across all pending states and union territories cast their votes.', importance='critical', category='Polling', status='pending', details={'phase': 7, 'final_phase': True}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 7, 23), title='Counting Day — Results Declared', description='Votes counted at designated counting centres under strict ECI supervision. Postal ballots counted first, followed by EVM rounds. Results declared progressively.', importance='critical', category='Results', status='pending', details={'method': 'EVM counting + VVPAT audit', 'begins': '8 AM'}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 7, 24), title='Final Results & Winner Declared', description='Election Commission announces final consolidated results. Winning candidates receive certificates of election.', importance='critical', category='Results', status='pending', details={'certificates': 'issued to winners'}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 7, 28), title='Government Formation Process', description='The President invites the party/coalition with majority (272+ seats) to form government. Leader of the majority party is appointed Prime Minister.', importance='critical', category='Government Formation', status='pending', details={'majority_seats': 272, 'total_seats': 543}, ), TimelineEvent( process_id=process.id, event_date=datetime(2026, 7, 30), title='Oath of Office — New Prime Minister', description='The new Prime Minister and Council of Ministers take the oath of office at Rashtrapati Bhavan, administered by the President of India.', importance='critical', category='Government Formation', status='pending', details={'location': 'Rashtrapati Bhavan', 'administered_by': 'President of India'}, ), ] for ev in events: db.session.add(ev) # ── Process steps ──────────────────────────────────────── steps = [ ProcessStep( process_id=process.id, step_number=1, title='Check & Complete Voter Registration', description=( 'Ensure you are enrolled in the Electoral Roll. ' 'You need an EPIC (Electors Photo Identity Card) — commonly called Voter ID. ' 'Apply online through the NVSP portal or visit your nearest ERO office.' ), key_points=[ 'Check your name on the electoral roll at nvsp.in', 'Apply for new Voter ID using Form 6 on the NVSP portal', 'Minimum age: 18 years on the qualifying date (1st January of the election year)', 'Carry Aadhaar, passport or other valid ID as address proof', 'NRIs can register as overseas electors via Form 6A', ], resources=[ {'name': 'NVSP Portal — Register Online', 'url': 'https://www.nvsp.in'}, {'name': 'Voter Helpline App', 'url': 'https://voterportal.eci.gov.in'}, {'name': 'ECI Official Website', 'url': 'https://eci.gov.in'}, ], estimated_time='15–30 minutes online', ), ProcessStep( process_id=process.id, step_number=2, title='Know Your Candidates & Parties', description=( 'Research the candidates contesting from your constituency. ' 'Review their affidavits, criminal records, educational qualifications, ' 'and financial details — all publicly available on the ECI website.' ), key_points=[ 'Check candidate affidavits on the ECI website', 'Review party manifestos and promises', 'Use MyNeta.info for candidate criminal and financial records', 'Watch election debates and rallies on news channels', 'Discuss with community and family — but vote independently', ], resources=[ {'name': 'MyNeta.info — Candidate Records', 'url': 'https://www.myneta.info'}, {'name': 'ECI Candidate Affidavits', 'url': 'https://affidavit.eci.gov.in'}, {'name': 'ADR — Election Analysis', 'url': 'https://adrindia.org'}, ], estimated_time='2–4 hours of research', ), ProcessStep( process_id=process.id, step_number=3, title='Locate Your Polling Booth', description=( 'Find your assigned polling station before Election Day. ' 'You can search using your EPIC number or name on the Voter Helpline App or NVSP portal. ' 'Polling stations are usually within 2 km of your residence.' ), key_points=[ 'Search your booth at nvsp.in using EPIC number', 'Download the Voter Helpline App for booth details and navigation', 'Check the polling date for your constituency (multi-phase elections)', 'Note booth number and address — plan your travel', 'Facilities for differently-abled voters are available at every booth', ], resources=[ {'name': 'NVSP — Find Your Polling Station', 'url': 'https://www.nvsp.in'}, {'name': 'Voter Helpline App', 'url': 'https://voterportal.eci.gov.in'}, ], estimated_time='5–10 minutes', ), ProcessStep( process_id=process.id, step_number=4, title='Cast Your Vote on Polling Day', description=( 'Visit your designated polling booth on the assigned polling date. ' 'Carry your EPIC card (Voter ID) or any of the 12 alternate photo IDs approved by ECI. ' 'Voting is by EVM with VVPAT verification for transparency.' ), key_points=[ 'Polling hours: 7:00 AM to 6:00 PM (may vary in some areas)', 'Carry EPIC or alternate photo ID (Aadhaar, Passport, PAN, Driving Licence, etc.)', 'Your left index finger will be marked with indelible ink', 'Press the button next to your chosen candidate on the EVM', 'Verify your vote on the VVPAT slip (visible for 7 seconds)', 'Maintain secrecy of your vote — it is your right', ], resources=[ {'name': 'ECI — How to Vote', 'url': 'https://eci.gov.in/how-to-vote/'}, {'name': 'Voter Helpline Number', 'url': 'tel:1950'}, ], estimated_time='15–45 minutes (including queue)', ), ProcessStep( process_id=process.id, step_number=5, title='Follow the Results', description=( 'After all phases of polling are completed, the ECI conducts counting on the designated Counting Day. ' 'Results are declared constituency by constituency. ' 'The party/coalition crossing 272 seats forms the government.' ), key_points=[ 'Counting begins at 8:00 AM on Counting Day', 'Postal ballots and service voters counted first', 'EVM results declared round by round', 'VVPAT slips of 5 randomly selected booths per constituency are cross-verified', 'Results available live on the ECI results portal', 'Majority mark: 272 out of 543 Lok Sabha seats', ], resources=[ {'name': 'ECI Results Portal', 'url': 'https://results.eci.gov.in'}, {'name': 'ECI Official Website', 'url': 'https://eci.gov.in'}, ], estimated_time='Results typically by evening of Counting Day', ), ] for step in steps: db.session.add(step) # ── FAQs ───────────────────────────────────────────────── faqs = [ FAQ(question='When is the 2026 Indian General Election?', answer='The 2026 General Election is expected to begin on 1 May 2026. Voting will be held in 7 phases from June to July 2026, with counting on 23 July 2026.', category='Schedule', order=1), FAQ(question='How do I register to vote in India?', answer='Register online at nvsp.in using Form 6, or visit your nearest Electoral Registration Officer (ERO). You need to be an Indian citizen aged 18+ on 1 January of the qualifying year.', category='Registration', order=2), FAQ(question='What is an EPIC / Voter ID card?', answer='EPIC stands for Electors Photo Identity Card. It is your primary voter identification issued by the Election Commission. You can apply online via the NVSP portal or Voter Helpline App.', category='Registration', order=3), FAQ(question='What ID do I need to carry on polling day?', answer='Carry your EPIC (Voter ID). ECI also accepts 12 alternate IDs including Aadhaar, Passport, PAN Card, Driving Licence, MNREGA Job Card, and others.', category='Voting', order=4), FAQ(question='What is an EVM and VVPAT?', answer='EVM (Electronic Voting Machine) is the device used for voting. VVPAT (Voter Verifiable Paper Audit Trail) prints a slip showing your vote for 7 seconds, adding transparency to the process.', category='Voting', order=5), FAQ(question='What is the Model Code of Conduct?', answer='The MCC is a set of guidelines issued by ECI that all parties and candidates must follow from announcement to completion of elections. It ensures free, fair, and peaceful elections.', category='Regulation', order=6), FAQ(question='Can NRIs vote in Indian elections?', answer='Yes! NRIs with Indian passports can register as overseas electors using Form 6A. They must be present at their polling booth in India on polling day.', category='Eligibility', order=7), FAQ(question='How many Lok Sabha seats are there?', answer='The Lok Sabha has 543 elected seats. A party or coalition needs at least 272 seats (simple majority) to form the government.', category='Electoral System', order=8), FAQ(question='What is NOTA?', answer='NOTA stands for None of The Above. It allows voters to reject all candidates. NOTA is the last option on every EVM. While it expresses dissent, it does not affect election results.', category='Voting', order=9), FAQ(question='How are votes counted?', answer='On Counting Day, EVMs are opened at designated centres under ECI supervision. Postal ballots are counted first, then EVM votes round by round. VVPAT slips from 5 random booths per constituency are cross-verified.', category='Results', order=10), FAQ(question='What happens after results are declared?', answer='The President of India invites the party/coalition with a majority to form the government. The PM and Council of Ministers take oath at Rashtrapati Bhavan.', category='Results', order=11), FAQ(question='Is voting compulsory in India?', answer='No, voting is not legally compulsory in India at the national level, but it is your democratic right and civic duty. Some states like Gujarat have provisions for compulsory voting in local elections.', category='Eligibility', order=12), ] for faq in faqs: db.session.add(faq) db.session.commit()