read 59 min
92 / 98
Apr 14

Day 78 of 100daysofcode : Avoiding Bugs in Password Reset Flows

Secure and Robust Password Reset Logic

Today’s focus is on designing a password reset flow that minimizes bugs and vulnerabilities. Here’s how to approach it conceptually:

  1. Input Validation First
  • Always validate user inputs (e.g., email format) before triggering actions like sending reset emails.
  • Check if the email/username exists in your system, but avoid revealing whether an account is registered (to prevent user enumeration).
  1. Token Management
  • Generate time-limited, single-use tokens for password resets. Ensure tokens expire after a short window (e.g., 15 minutes).
  • Invalidate tokens immediately after use or if a new reset request is made.
  1. Idempotency & State Handling
  • Guard against duplicate submissions (e.g., double-clicking the “Reset” button).
    Track the state of reset requests to prevent invalid token reuse or mid-process hijacking.
  1. Secure Communication
  • Send reset links via HTTPS-only channels.
  • Mask sensitive details (like tokens) in URLs for logs or error messages.
  1. User Feedback Without Leaks
  • Use generic error messages (e.g., “If this email exists, a reset link was sent”) to avoid exposing user data.
  • Confirm success/failure clearly but never disclose internal system details.
  1. Rate Limiting
  • Throttle repeated reset requests to prevent abuse (e.g., email bombing or brute-force attacks).
  1. Post-Reset Hygiene
  • Invalidate all active sessions after a password reset to force re-authentication.
  • Log the event for security audits.

A secure password reset flow balances user convenience with rigorous error handling and state management. Always test edge cases (expired tokens, invalid inputs, network interruptions) to catch bugs early.
lebanon-mug

Day 79 of 100daysofcode : Cybersecurity Critical for Software Engineers

  1. Why Cybersecurity Matters
  • Data breaches cost companies millions and damage reputations (e.g., Equifax, SolarWinds).
  • Secure coding prevents vulnerabilities like SQL injection, XSS, and insecure APIs.
  • Compliance (GDPR, HIPAA) requires engineers to build systems that protect user privacy.
  • Career growth: Security-aware developers are in high demand for roles like DevSecOps, security architects, or penetration testers.
  1. Common Vulnerabilities
  • OWASP Top 10 (e.g., broken access control, insecure deserialization).
  • Misconfigured cloud storage (e.g., exposed S3 buckets).
  • Hardcoded secrets (API keys, passwords) in code.
  1. Secure Development Lifecycle (SDL)
  • Integrate security into every phase: design, coding, testing, deployment.
  • Tools like SAST (Static Application Security Testing) and DAST (Dynamic Testing).

Why This Matters for Your Goals

  • Future-proofing: Companies prioritize engineers who minimize risks.
  • Trust: Secure apps earn user/customer confidence.
  • Career flexibility: Cybersecurity skills open doors to high-impact roles in fintech, healthcare, or government.

“Security is not a product, but a process.” — Bruce Schneier
By embedding security into your coding practice today, you’ll become a developer who builds resilient systems and stands out in the job market. :shield:
lebanon-mug

Day 80 of 100daysofcode : The Unseen Power of the Single Responsibility Principle

Today’s focus isn’t about syntax or frameworks—it’s about a mindset shift. Let’s talk about the Single Responsibility Principle (SRP), the unsung hero of clean, scalable, and maintainable code.

A. What is SRP?

Imagine a chef in a kitchen. If they’re busy chopping veggies, cooking steak, and plating desserts, chaos ensues. But if each chef focuses on one task, the kitchen runs smoothly. SRP is that specialization: one class/module = one job.

B. Why SRP Matters

  1. Clarity Over Chaos: When a component does only what it’s designed for, reasoning about its behavior becomes effortless.
  2. Easier Maintenance: Need to tweak a feature? You’ll only touch the part responsible for it—no domino effect.
  3. Reusability: Components with single purposes are like LEGO blocks. They fit anywhere without forcing workarounds.
  4. Testability: Testing a focused, single-responsibility unit? Simple. Testing a tangled mess? A nightmare.

C. The Cost of Ignoring SRP

Underestimating SRP leads to “God Classes”—components that do everything but excel at nothing. They become fragile, hard to debug, and resistant to change. Ever tried untangling spaghetti? That’s your future codebase without SRP.

D. A Mindset, Not Just a Rule

SRP isn’t about splitting code into microscopic pieces. It’s about intentional design. Ask: “What is this component’s true purpose?” If the answer includes “and,” rethink.

Tomorrow’s you will thank today’s you for embracing SRP. It’s the difference between a codebase that scales gracefully and one that collapses under its own weight. Don’t cut corners—cut responsibilities instead.

:link: Stay disciplined. Code with intent.
lebanon-mug

Day 81 of 100daysofcode : The “O” in SOLID: Open/Closed Principle (OCP)

The Open/Closed Principle states that software entities (classes, modules, functions) should be open for extension but closed for modification. In agile terms, this means designing systems that evolve without rewriting existing code, aligning perfectly with iterative development and changing requirements.

Why OCP Matters in Agile?
Agile thrives on adaptability. By building code that’s extensible, teams can:

  • Add features rapidly without breaking existing functionality.
  • Reduce regression risks (no need to retest unchanged code).
  • Empower parallel workstreams (devs extend, don’t collide).

Applying OCP in Flutter

  1. Leverage Abstraction
  • Define abstract classes or interfaces for core behaviors (e.g., AuthRepository). New implementations (like Firebase or REST APIs) can be added without altering existing code.
  1. Composition Over Inheritance
  • Design widgets as reusable, composable pieces (e.g., a base BaseThemeWidget with customizable styles via injected themes). Extend via composition, not inheritance.
  1. Dependency Injection
  • Inject dependencies (e.g., services, repositories) through constructors. Swap implementations (e.g., mock vs. production) without touching the widget’s core logic.
  1. Plugin Architecture
  • Use strategy patterns for platform-specific code (e.g., file storage). Add new platforms by extending strategies, not modifying core logic.
  1. State Management
  • Abstract state logic (e.g., BlocBase in BLoC) to allow new event handlers or states without refactoring existing workflows.

Agile Wins with OCP

-Faster Sprints: Focus on new code, not retrofitting old code.

  • Cleaner Merges: Less overlap in code changes = fewer conflicts.
  • Future-Proofing: New team members can extend features without deep legacy knowledge.

Think Differently
In Flutter, OCP isn’t just about classes—it’s about designing for uncertainty. Agile teams thrive when the codebase embraces change as a first-class citizen. Tomorrow’s feature is just an extension, not a rewrite!

Next: The “L” in SOLID—keeping your Flutter app substitutable and resilient!
lebanon-mug

Day 82 of 100daysofcode : The Liskov Substitution Principle (LSP)

What is the Liskov Substitution Principle?

Imagine building a LEGO castle where every block seamlessly fits into the same slot as its “parent” block. LSP states that subtypes (child classes) should be substitutable for their base types (parent classes) without breaking the system. If a subclass can’t replace its parent in all scenarios without causing errors or unexpected behavior, it violates LSP.

Why is LSP Important?

LSP ensures that your codebase remains flexible and predictable as it grows. By designing classes to honor their parent’s “contract” (behavior and expectations), you:

  1. Avoid hidden bugs when swapping implementations.
  2. Simplify testing (subclasses behave as expected).
  3. Reduce tight coupling between components, making code easier to refactor.

Future Impact of LSP

When you finish your software, adhering to LSP means:

  1. Effortless Scaling: Adding new features or subclasses won’t destabilize existing systems.
  2. Confident Collaboration: Team members can extend your code without fear of breaking legacy functionality.
  3. Resilient Architecture: Your software evolves gracefully, like a puzzle where new pieces fit perfectly into old slots.

Scenario:

  1. Create a base class Bird with generic behaviors (e.g., eat()).
  2. Create a subclass FlyingBird (with fly()) and NonFlyingBird (without fly()).
    Now, Eagle inherits from FlyingBird, and Penguin from NonFlyingBird.

Future Reflection:

  1. Safe Extensions: Later, adding a Duck or Ostrich won’t break existing logic.
  2. Clear Contracts: Developers know which birds can fly without guessing.
  3. Zero Surprises: Functions expecting FlyingBird can trust fly() works, while NonFlyingBird subtypes focus on their unique traits (e.g., swim()).

Takeaway:
LSP guides you to model hierarchies truthfully. By honoring substitution, your software grows like a well-organized library—every new “book” (class) fits neatly into the right section, and users never stumble over misplaced logic.
lebanon-mug

Day 83 of 100daysofcode : Interface Segregation Principle (ISP)

Imagine building a robot that can cook, clean, and paint. Instead of forcing every robot to carry all these features (even if they only need one), you design separate “toolkits” for cooking, cleaning, and painting. Each robot picks only the tools they need. No extra weight, no unused buttons, no confusion. That’s ISP!

Why It Reflects Positively on Your Project:

  1. No Bloat, Just Focus
    By avoiding “one-size-fits-all” interfaces, your code stays lean. Components only depend on what they actually use, making your project easier to debug and extend.
  2. Change Without Fear
    Need to tweak the “cooking” logic? No risk of breaking the “painting” module! Changes stay isolated, reducing unintended side effects.
  3. Teamwork-Friendly
    Developers work on smaller, well-defined pieces without stepping on each other’s toes. Less merge conflict drama!
  4. Future-Proof Design
    Adding a new feature (like “baking”) doesn’t mean rewriting old code. Just plug in a new, specific interface.

ISP is like designing a LEGO set—small, specialized pieces snap together to build something amazing. When your project wraps up, you’ll appreciate how this principle kept your codebase clean, adaptable, and ready for whatever comes next.
lebanon-mug

Day 84 of 100daysofcode : Dependency Inversion Principle (DIP)

What is the Dependency Inversion Principle (DIP)?

The DIP flips traditional dependency hierarchies to reduce rigid, brittle code. It has two core ideas:
:one: High-level modules (core logic) should not depend on low-level modules (details like databases or APIs). Instead, both should depend on abstractions (like interfaces).
:two: Abstractions should define what needs to be done, not how. Concrete implementations (details) must adhere to these abstractions.

Example: Imagine a universal remote control. Instead of being hardwired to one device (e.g., a TV), it communicates through a standard interface (e.g., infrared signals). Now it can work with any device that “implements” that interface!

“How Does DIP Help Me Today?” :thinking:

  • Test Smarter: Replace real databases or services with mock versions during testing, since they follow the same interface.
  • Swap Components Easily: Change payment gateways, logging tools, or APIs without rewriting your core logic.
  • Future-Proof Code: New features or third-party tools integrate smoothly if they align with your abstractions.
  • Cleaner Collaboration: Teams can work on different modules simultaneously by agreeing on interfaces upfront.

Future Benefits of DIP

  1. Faster Scaling: Add new functionality by extending abstractions, avoiding risky rewrites.
  2. Lower Maintenance Costs: Isolate changes to specific modules, reducing unintended side effects.
  3. Adapt to Trends: Integrate emerging tech (AI, blockchain, etc.) by wrapping them in existing abstractions.
  4. Reusability: Share modules across projects if they rely on common interfaces rather than concrete details.

FAQ :question:

Q: Is DIP the same as Dependency Injection?
A: No! Dependency Injection is a technique to achieve DIP (by passing dependencies into classes). DIP is the guiding principle of relying on abstractions.

Q: Won’t creating interfaces slow me down?
A: Focus on critical areas first (e.g., external services, volatile code). Over-engineering is avoidable—balance flexibility with simplicity.
lebanon-mug

Day 85 of 100daysofcode : Embracing AI as Software Engineers

The integration of Artificial Intelligence (AI) into software development isn’t just a trend—it’s a fundamental shift reshaping how we build, optimize, and scale applications. Here’s why AI matters and how you, as a software engineer, can leverage it:

Why AI is Transforming Software Development

  1. Automation of Repetitive Tasks: AI tools streamline workflows like code reviews, testing, debugging, and deployment, freeing developers to focus on creative problem-solving.
  2. Enhanced User Experiences: AI enables personalization (e.g., recommendation engines), real-time analytics, and adaptive interfaces, making apps smarter and more intuitive.
  3. Data-Driven Decisions: AI-powered analytics help identify patterns, predict user behavior, and optimize performance, turning raw data into actionable insights.
  4. Smarter Applications: From chatbots (NLP) to image recognition (CV), AI adds advanced capabilities that elevate your software’s value proposition.
  5. Competitive Edge: Companies increasingly prioritize AI-driven solutions—adopting these skills keeps you relevant in a fast-evolving industry.

Why Learn AI as a Software Engineer?

  1. Career Growth: AI expertise is in high demand across industries, opening doors to roles like AI Engineer, ML Developer, or AI Product Architect.
  2. Future-Proofing: Understanding AI basics (like neural networks, training models, or APIs) prepares you to adapt as tools like GitHub Copilot or AI-driven DevOps become mainstream.
  3. Innovation: Even basic AI knowledge lets you prototype ideas faster, whether it’s automating workflows or enhancing apps with generative AI.
  4. Collaboration: Bridge the gap between software teams and AI specialists by speaking their language and integrating their models effectively.

How to Start Integrating AI into Your Projects

  1. Leverage APIs & SDKs: Use platforms like OpenAI, Google Cloud AI, or AWS SageMaker to add pre-built AI features (e.g., text generation, speech recognition) without building models from scratch.
  2. Adopt Pre-Trained Models: Frameworks like TensorFlow, PyTorch, or Hugging Face offer ready-to-use models for common tasks (e.g., sentiment analysis, object detection).
  3. Understand Data Pipelines: AI thrives on data. Learn to clean, preprocess, and manage datasets to train or fine-tune models effectively.
  4. Focus on Ethics: Address biases, privacy concerns, and transparency when deploying AI to build trust and compliance.
  5. Experiment Incrementally: Start small—add a chatbot to your web app, implement smart search, or automate QA testing with AI tools.

AI isn’t replacing developers—it’s empowering us to solve bigger problems, faster. By learning to interact with AI tools and frameworks, you’ll unlock new dimensions of creativity and efficiency in your projects. Dive into tutorials, experiment with APIs, and stay curious!
lebanon-mug

Day 86 of 100daysofcode : REST API Pro Tips - Status Codes, Methods & Authentication

Essential REST API concepts every developer should know! Here’s your cheat sheet:

  1. HTTP Status Codes Matter

Success (200 OK, 201 Created)
Redirects (301 Moved Permanently)
Client errors (400 Bad Request, 401 Unauthorized, 404 Not Found)
Server errors (500 Internal Server Error)
Always return appropriate status codes for clear API responses!

  1. HTTP Methods = CRUD Operations

GET: Retrieve data (safe & idempotent)
POST: Create new resource (not idempotent)
PUT: Update entire resource
PATCH: Partial updates
DELETE: Remove resource
Use methods semantically!

  1. Authentication Essentials

API Keys: Simple but less secure (pass in headers)
JWT (Bearer Tokens): Stateless, self-contained tokens
OAuth2: Industry standard for delegated auth
Always use HTTPS for auth endpoints!

BONUS Best Practices

Use nouns for endpoints (/users, not /getUsers)
Version your API (/api/v1/resource)
Add rate limiting
Document with OpenAPI/Swagger
Handle errors gracefully with messages

What API tips would you add? Let’s level up together!
lebanon-mug

Day 87 of 100daysofcode : Why You Need Two Awaits for API Calls

Today I learned why two await keywords are crucial when working with async API calls! Here’s why:

:one: First await : Resolves the HTTP request (gets response headers)
:two: Second await : Parses the response body as JSON (can be slow/large)

Real-World Analogy
It’s like ordering coffee:

  1. Wait for your order to be taken (first await)
  2. Wait again for the coffee to be made (second await)
    Skipping the second wait = getting an empty cup!

Key Takeaways:

fetch() returns a Promise for the network request
.json() returns another Promise for body parsing
Async operations need to be fully awaited at every stage

Always add error handling with try/catch around your awaits!
lebanon-mug

Day 88 of 100daysofcode : Flutter Routing Revolution with go_router!

Today I leveled up my Flutter skills by diving into go_router - a powerful routing package that’s become my new navigation superhero! Here’s why it’s awesome:

Why go_router Rocks:

:one: Declarative Routing
Define all routes in one clean, organized place with GoRouter configuration. No more messy Navigator.push() spaghetti code!

:two: Deep Linking Made Easy
Seamlessly handle web URLs and deep links - perfect for web apps and dynamic content. Just define paths once and it “just works”!

:three: Nested Navigation
Handle complex UIs with nested routes (perfect for bottom nav bars with their own stacks)!

Why Better Than Traditional Routing?

Navigator 1.0: Requires manual stack management (push/pop hell!)
Other Packages: Often need more boilerplate for similar features
Type-Safe: Parameters are validated through path syntax
Web-Ready: Built-in support for browser forward/back buttons

Killer Features:

context.go() (replace entire stack) vs context.push() (add to stack)
Route-specific page transitions
Query parameter support out-of-the-box
Built-in error page handling

The Result?
Cleaner code, better navigation flows, and web support in half the time! If you’re still using basic Navigator methods, give go_router a try - it’s maintained by the Flutter community and keeps getting better!
lebanon-mug

Day 89 of 100daysofcode : Understanding Clean Architecture in Flutter🧹

Ever heard of Clean Architecture but unsure how it applies to Flutter? Let’s demystify it!

What is Clean Architecture?

It’s a design pattern that organizes code into layers to separate concerns, making apps more scalable, testable, and maintainable. The core idea: dependencies flow inward, and inner layers don’t depend on outer layers.

The 3 Key Layers

  1. Presentation Layer (UI)
    What: Widgets, state management (e.g., Cubit, Provider), and UI logic.
    Why: Handles how data is displayed.
    Rule: Never contains business logic!
  2. Domain Layer (Core Business Logic)
    What: Entities (business models), use cases (app features), and repository interfaces.
    Why: Defines what the app does, independent of frameworks or data sources.
    Rule: Pure Dart—no Flutter dependencies!
  3. Data Layer (Data Sources)
    What: Repositories (implementation), APIs, databases, local storage.
    Why: Fetches/stores data (e.g., REST API ↔ Domain).
    Rule: Implements interfaces defined in the Domain layer.

How It Fits in Flutter

  • Independence: Change your UI (Presentation) or switch databases (Data) without breaking business logic (Domain).
  • Testability: Test Domain layer without Flutter dependencies; mock Data layer for UI tests.
  • Scalability: Add features or refactor code with minimal ripple effects.

Why You’ll Love It

Future-proof: Adapt to new libraries/frameworks easily.
Test-friendly: Isolate layers for unit/integration tests.
Team-ready: Clear separation simplifies collaboration.

Quick Tips for Flutter

Use dependency injection (e.g., get_it, riverpod) to connect layers.
Keep the Domain layer pure (no BuildContext or widgets).
Start small! Even splitting UI and logic is a win.

Clean Architecture isn’t about perfection—it’s about intentional structure.
lebanon-mug

Day 90 of 100daysofcode : Demystifying BLoC and Cubit in Flutter — their core philosophies, use cases, and why your 2025 projects might lean toward one!

BLoC vs. Cubit: The Heart of the Matter

  1. What is BLoC?

Definition: BLoC (Business Logic Component) is an event-driven state management pattern. It processes incoming events, transforms them through asynchronous logic, and outputs new states.
Use Cases:

  • Apps requiring complex event handling (e.g., real-time data streams, multi-step workflows).
  • Projects needing traceability for debugging (every state change is tied to a specific event).
  • Teams that benefit from strict separation between UI and business logic (event contracts act as clear boundaries).
  1. What is Cubit?

Definition: Cubit (a lightweight subset of BLoC) is a simpler state management tool. It uses methods to directly emit state changes without events.
Use Cases:

  • Apps with straightforward logic (e.g., counters, forms, toggle switches).
  • Rapid prototyping or solo projects where minimal boilerplate speeds up development.
  • Scenarios where simplicity and readability outweigh the need for event tracking.

When Should You Use Them?

BLoC shines when:
You’re handling async operations like API calls with retries, debouncing, or complex error handling.
Your app’s logic resembles a state machine (e.g., authentication flows, payment gateways).
Debugging requires event-level granularity (e.g., logging every user action).
Cubit thrives when:
You want to ship fast without over-engineering.
Your state changes are linear and predictable (no middleware or event transformations).
You value readability (methods like increment() are self-documenting).

In 2025, Cubit will likely dominate for everyday apps, while BLoC remains the guardian of complex, large-scale systems. Choose tools that match your problem — not trends!
lebanon-mug

Day 91 of 100daysofcode : Flutter Networking Showdown: Dio vs. HTTP Package

Understanding when to use Dio or the basic http package in Flutter

:one: Simplicity vs. Power:

  • http: Lightweight, minimal setup. Perfect for straightforward REST API calls (GET, POST).
    -Dio: Feature-packed! Built-in interceptors, file uploads/downloads, request cancellation, timeout control, and more.

:two: Error Handling:

  • http: Manual error checking. You parse status codes and responses yourself.
  • Dio: Detailed error objects with status codes, messages, and response data—saves debugging time!

:three: Customization:

  • http: Limited configuration. You handle headers, encoding, and decoding manually.
  • Dio: Global configuration (base URLs, headers), interceptors for logging/auth, and support for FormData (multipart uploads).

:four: Extras:

  • Dio: Progress tracking for uploads/downloads, request retries, and plugin support (e.g., Dio Cache for caching).
  • http: Need extras? You’ll likely add third-party packages.

When to Choose?

:heavy_check_mark: Use http if:

  • Your project is small or requires minimal networking.
  • You prefer lightweight dependencies or need basic API interactions.

:heavy_check_mark: Choose Dio if:

  • Your app demands advanced features (interceptors, file handling).
  • You want less boilerplate for error handling and configuration.
  • Complex APIs or large-scale projects benefit from structured workflows.

Both packages shine in their own lanes! The http package is your go-to for simplicity, while Dio acts like a Swiss Army knife for robust, scalable networking. Your choice depends on the project’s needs and your appetite for built-in tools vs. DIY solutions.
lebanon-mug

Day 92 of 100daysofcode : Why Your Flutter App Needs a Logger File

Today’s focus was on implementing a logger file in my Flutter app. At first glance, logging might seem like a “nice-to-have” feature, but after diving deep, I realized it’s a non-negotiable tool for building robust, maintainable apps. Here’s why:

:one: Debugging Without the Blindfold

Without structured logging, debugging feels like searching for a needle in a haystack. A logger acts as a time-travel machine, showing you exactly what happened before a crash or unexpected behavior. Instead of guessing, you get a step-by-step narrative of events, errors, and user interactions.

:two: Production Monitoring Superpowers

When your app is live, you can’t stare at the console 24/7. A logger file:

  • Captures hidden errors users encounter but don’t report.
  • Tracks performance bottlenecks (e.g., slow API calls, heavy widget rebuilds).
  • Helps recreate issues by preserving the app’s state and user journey.

:three: User Behavior Insights

Logging isn’t just for crashes! It quietly observes how users interact with your app. Which features are popular? Where do they get stuck? These insights drive data-driven decisions for future updates.

:four: Structured & Filtered Output

A good logger lets you:

  • Categorize logs by severity (e.g., verbose, debug, error).
  • Filter out noise to focus on critical issues.
  • Format logs for readability, even when thousands of lines pile up.

:five: Security & Compliance

For apps handling sensitive data, logs can:

  • Audit unauthorized access attempts.
  • Track data flow to ensure compliance with regulations (e.g., GDPR).

:six: Future-Proof Collaboration

Working in a team? A shared logging standard ensures everyone speaks the same “debugging language.” New developers can onboard faster, and legacy code becomes less intimidating.

:seven: Crash Reports That Actually Help

Integrate your logger with crash-reporting tools, and suddenly, every crash report comes with context. No more vague “something went wrong” emails from testers!

:eight: Environment-Aware Logging

Turn off noisy logs in production but keep them active in development. A logger lets you control visibility without redeploying your app.

The Bigger Picture :star2:

Logging isn’t just about fixing bugs—it’s about owning your app’s story. It empowers you to understand, optimize, and scale with confidence.
lebanon-mug

Day 93 of 100daysofcode : Integrating Azure Face Detection AI into MERN Project

Objective:
Implement Azure’s Face Detection AI to verify user authenticity (detect real users vs. fake/spoofed images) during registration/login in my MERN stack application.

Workflow Illustration

  1. Frontend (React):
    • Created a user verification component with a live camera feed.
    • Added a prompt for users to capture a live selfie (to prevent pre-recorded images).
    • Designed UI feedback (loading states, success/error alerts).
  2. Backend (Node.js/Express):
  • Set up an API endpoint /api/verify-user to handle image verification requests.
  • Integrated Azure Face API Client SDK to analyze the uploaded image.
  • Configured environment variables to securely store Azure API keys/endpoints.
  1. Azure Face Detection AI:
  • Used the Liveness Detection feature to check if the captured image is from a live person.
  • Analyzed spoofing indicators (e.g., screen reflections, paper masks, depth sensors).
  • Extracted confidence scores to determine “real” (score ≥ 75%) or “fake” (score < 75%).
  1. Database (MongoDB):
  • Added a isVerified field to the user schema to track verification status.
  • Updated the user document post-successful verification.

Key Challenges & Solutions

Security: Avoided exposing Azure credentials by processing images server-side.
Latency: Optimized image compression to reduce API response time.
Error Handling: Added fallback checks for edge cases (e.g., poor lighting, multiple faces).

Outcome

  • Users must complete liveness verification before accessing sensitive features.
  • Reduced fake account creation by 80% during testing.
  • Azure’s AI provided actionable insights (e.g., “face too blurry”, “no face detected”).
    lebanon-mug

Day 94 of 100daysofcode : Demystifying the Pubspec.yaml in Flutter – The Heart of Your Project

Today, I dove into the backbone of every Flutter project: the pubspec.yaml file. This unassuming YAML file is the control center for your app’s configuration, dependencies, and resources. Here’s why it’s a non-negotiable part of Flutter development:

What is Pubspec.yaml?

  • It’s the configuration file that defines your app’s identity, dependencies, and assets.
  • Think of it as the “recipe” that tells Flutter how to build and manage your project.

Key Components & Their Roles

  1. App Metadata: Name, version, and description for your app (critical for publishing).
  2. Dependencies: External packages/plugins your app relies on (e.g., HTTP, state management, UI libraries).
  3. Asset Management: Declares images, fonts, and other files bundled with your app.
  4. Environment Settings: Specifies Flutter/Dart SDK constraints to ensure compatibility.
  5. Flutter-Specific Configs: Custom configurations like generating platform-specific code.

Why Pubspec.yaml Matters

-Centralized Control: Every resource, tool, or package your app uses is tracked here.
-Dependency Management: Simplifies adding, updating, or removing third-party tools.
-Version Consistency: Ensures everyone on the team uses compatible package versions, avoiding “it works on my machine” issues.
-Asset Organization: Keeps fonts, images, and configs structured and accessible.
-Collaboration Ready: A well-maintained pubspec.yaml makes onboarding new devs seamless.

Final Thoughts

The pubspec.yaml is where your app’s ecosystem comes together. Misconfigure it, and you’ll face build errors or missing assets; master it, and you unlock smooth development workflows. Tomorrow, I’ll explore dependency versioning strategies to keep projects stable!

Pro Tip: Always validate your pubspec.yaml syntax—YAML’s indentation rules can be sneaky!
lebanon-mug

Day 95 of 100daysofcode : I’m Teaching My Apps & Websites to Think! :robot:

The big revelation?
As a software engineer, I’ve always built logic into my apps. But today’s tech world demands more: intuition. So this week, I dove into AI integration—not to replace my code, but to evolve it. Here’s what I’ve been up with AI tools!

Why AI?
Imagine apps that anticipate user needs, websites that learn from behavior, or tools that debug themselves. That’s the power of blending AI with engineering. My goal? Make my projects smarter, not harder.

What I Explored:

  1. AI-Powered Chatbots
    No more rigid scripts! Tools like Dialogflow let me build bots that understand context and reply like humans.
  2. Smart Recommendations
    Used TensorFlow.js to add “You might also like…” features that adapt in real-time based on user actions.

Lessons Learned:

  • AI isn’t magic—it’s a tool. You still need clean data, clear goals, and solid code.
  • Start small: A tiny AI feature (like a sentiment analyzer) can add HUGE value.
  • Ethics matter. Bias in AI is real—engineers have to build responsibly.

Why This Matters:
Users don’t care how your app works—they care if it feels effortless. AI helps bridge that gap between functionality and delight.

Would you trust a chatbot that learns from you? :wink:
lebanon-mug

Day 96 of 100daysofcode : AI Agents, No-Code vs. Code, and Strategic Choices

Today’s workshop on Building AI Agents was a deep dive into the future of intelligent systems! Here’s a breakdown of what we covered, plus reflections on no-code vs. code approaches for app integration:

Workshop Highlights:

  • Wiser AI Framework: Designing agents that prioritize context-aware decision-making—like balancing user intent, ethics, and efficiency.
  • Prompting Strategies: Crafting prompts that act as “training wheels” for AI, shaping its logic without rigid scripting.
  • AI Agent vs. Chatbot: Chatbots react; AI agents proact—they learn, adapt, and make decisions (e.g., automating workflows vs. negotiating deadlines).
  • Data as the Brain: How structured datasets and real-time inputs create an AI’s “memory” and personality.

No-Code vs. Code: Building AI Agents

We debated the pros and cons of both approaches:

  1. No-Code Platforms (e.g., Voiceflow, Zapier):
    :white_check_mark: Speed: Launch prototypes fast, ideal for testing ideas or simple automation.
    :white_check_mark: Accessibility: No programming expertise needed.
    :x: Limitations: Less customization, constrained logic, and dependency on third-party security protocols.
  2. Custom-Coded Agents (Python, LangChain, etc.):
    :white_check_mark: Flexibility: Full control over logic, data flow, and integrations.
    :white_check_mark: Scalability: Tailor-made for complex tasks (e.g., dynamic decision trees, sensitive data handling).
    :x: Resources: Requires time, technical skills, and robust security infrastructure.

Security & Suitability for My Apps

  • No-Code: Quick for MVPs or internal tools, but risks exist if third-party platforms have data privacy gaps.
  • Custom Code: Better for user-facing apps with sensitive data—you own the security layers, encryption, and compliance.

Why This Matters for Me

I’m exploring these options to answer:

Should my apps leverage no-code AI for speed, or invest in coded solutions for scalability and control?

Key Takeaway

No-code = speed, Code = power + security. For customer-facing apps with complex needs, coding might be the winner—but hybrid approaches (no-code for prototyping, code for scaling) could bridge the gap!

Excited to experiment tomorrow!
lebanon-mug

Day 97 of 100daysofcode : Celebrating the MongoDB Aficionado Badge! :tada:

Today’s a milestone day, I just earned the MongoDB “Aficionado” badge! This badge is awarded for visiting MongoDB for 100 consecutive days (that’s over three months of daily dedication!), and here’s the kicker: I’m one of only 27 people in the entire MongoDB community to earn this badge so far! What started as a small goal turned into an incredible journey of learning, persistence, and growth—and I’m thrilled to be part of such an exclusive group!

  1. What I Learned Along the Way
  • Deep Dive into MongoDB: Over these 100 days, I’ve mastered core concepts like data modeling, query optimization, aggregation pipelines, and other development and business stuff. I even explored MongoDB Atlas for cloud database management, indexing strategies to turbocharge performance, and transactions for ACID compliance.
  • Real-World Projects: Built a full-stack app with user authentication, a real-time analytics dashboard, and a RESTful API—all powered by MongoDB’s flexibility and scalability.
  • Consistency Trumps All: Some days were tough (hello, burnout!), but showing up daily—even for 30 minutes—taught me the power of tiny, consistent efforts.
  1. Why This Badge Matters

The Aficionado badge isn’t just about streaks, it’s proof that discipline compounds into expertise. MongoDB became my go-to tool for unstructured data, and I now appreciate its role in modern apps (from startups to Fortune 500 companies!). The fact that only 27 people globally have earned this badge (so far!) adds a layer of pride, it’s a reminder that sticking to hard goals pays off in rare, meaningful ways.

  1. Key Takeaways for Fellow Coders
  • Build Daily Habits: Even 15 minutes of coding daily adds up. You don’t need to be perfect, just persistent.
  • Embrace Challenges: Debugging complex queries or optimizing slow operations taught me patience and problem-solving.
  • Community Rocks: MongoDB’s docs, forums, and Discord kept me motivated. Never underestimate the power of asking for help!
  • Stand Out: Being part of a tiny group (like the 27 Aficionados!) shows that uncommon consistency leads to uncommon results.

To anyone on the fence about starting 100daysofcode : DO IT. You’ll surprise yourself with how much you grow. And who knows? You might even earn a shiny badge or two along the way—or join an elite club like the MongoDB Aficionados.

Have you used MongoDB? What’s your favorite feature?
lebanon-mug

This topic will automatically close in 3 months.