Why Swapio
What makes it better
than the alternatives
- 01
Category-specific ad forms
Separate input fields for motors (make, model, year, doors, transmission), property (bedrooms, bathrooms, area, furnishing), electronics, wholesale, jobs and general items, all driven by database attributes
- 02
Swap requests
Members can offer one of their own ads in exchange for another, creating a barter flow alongside cash sales
- 03
Job marketplace
Company profiles, job posts by recruiters, candidate profiles, applications, and an accept/reject workflow with payment on hire
- 04
Three admin roles
SuperAdmin (full access), Admin (approvals and moderation), Operation (view-only reports), each enforced by [Authorize(Roles = ...)] on every controller
- 05
No default secrets
JWT_KEY, database passwords and the first admin password must be supplied in .env; startup fails otherwise, preventing accidental deployment with placeholder credentials
Public Website (ASP.NET Core MVC)
- Home page with category tiles
- featured ads
- city selector and search bar (Areas/Website/Views/Home/Index.cshtml)
- Ad browsing by category
- sub-category
- city
- price range and category-specific filters (Areas/Website/Controllers/PostController.cs CategoryMotor action)
- Ad detail pages for motors
- property
- electronics
- wholesale
- jobs and general items
- each with category-specific fields (Areas/Website/Views/Post/MotorProductDetails.cshtml and 5 others)
- Member sign-up
- sign-in
- profile edit
- password reset (Areas/Website/Controllers/AuthController.cs
- MemberAuth.SignInAsync)
- Post ad forms with photo/video upload
- category selection
- then category-specific inputs (Areas/Website/Views/Post/PostAdMotor.cshtml and 5 others)
- My Ads page with tabs for Active
- Pending
- Rejected
- Expired (Areas/Website/Views/Post/MyProfile.cshtml)
- Favourites list
- chat inbox
- notifications (Areas/Website/Controllers/PostController.cs MyFavourite
- ChatList
- Notification actions)
- Swap request flow: offer one of your ads for another (Areas/Website/Controllers/PostController.cs SwapRequest action)
- Job pages: company profile
- job post
- candidate profile
- apply (Areas/Website/Views/Post/JobRecuterDetails.cshtml
- JobCandicateDetails.cshtml)
- Terms
- privacy
- support contact pages (Areas/Website/Views/Post/TermsCondition.cshtml
- PrivacyPolicy.cshtml
- Support.cshtml)
- English and Arabic UI with right-to-left layout (wwwroot/Areas/Website/src/css/swapio.css
- .rtl rules)
Admin Panel (ASP.NET Core MVC)
- Dashboard with sales chart
- order chart
- total ads
- total members
- pending ads
- pending jobs (Areas/Admin/Views/Dashboard/Index.cshtml
- DashboardController.cs)
- Ad management: approve
- reject
- delete
- view details (Areas/Admin/Controllers/PostController.cs
- Views/Post/Index.cshtml with DataTables)
- Member management: list
- view profile
- activate
- deactivate (Areas/Admin/Controllers/MemberController.cs
- Views/Member/Index.cshtml)
- Category management: add
- edit
- delete categories and sub-categories (Areas/Admin/Controllers/CategoryController.cs
- Views/Category/Index.cshtml)
- Attribute management: define category-specific fields (make
- model
- bedrooms
- etc.) with type (text
- dropdown
- checkbox) (Areas/Admin/Controllers/AttributeController.cs)
- City and country management (Areas/Admin/Controllers/CityController.cs
- CountryController.cs)
- Banner management: upload images
- set category
- order (Areas/Admin/Controllers/BannerController.cs)
- Boost plan management: create plans with price
- duration
- top position (Areas/Admin/Controllers/BoostPlanController.cs)
- Job post approval: approve or reject company profiles and job posts (Areas/Admin/Controllers/JobController.cs)
- Candidate approval: approve or reject candidate profiles (Areas/Admin/Controllers/CandidateController.cs)
- Push notification sender: compose and send to all members (Areas/Admin/Controllers/NotificationController.cs SendNotification action)
- Feedback inbox: read messages from the support form (Areas/Admin/Controllers/FeedbackController.cs)
- Reports: ad report with Excel/PDF export
- job report (Areas/Admin/Controllers/ReportController.cs PostReport
- JobReport actions)
- User management: add
- edit
- delete admin panel users with role selection (Areas/Admin/Controllers/UserController.cs)
- Terms and privacy editor: update the public pages (Areas/Admin/Controllers/TermsConditionController.cs
- PrivacyPolicyController.cs)
- Three roles enforced: SuperAdmin (all actions)
- Admin (approvals
- moderation
- reports)
- Operation (view-only reports) (Infrastructure/Auth.cs AuthRoles
- [Authorize(Roles = ...)] on each controller)
Mobile App (Flutter 3.35, Android/iOS)
- Home screen with category grid
- featured ads
- search bar
- city selector (lib/ui/fragment/home/HomePage.dart)
- Category browsing with filters: price
- city
- sub-category
- category-specific attributes (lib/ui/activity/categoriy/CategoryMotor.dart
- filter/FilterPage.dart)
- Ad detail screens for motors
- property
- electronics
- wholesale
- jobs
- general (lib/ui/activity/productItemDetails/motor/MotorProductDetailsPage.dart and 5 others)
- Post ad flow: select category
- fill category-specific form
- upload photos/video (lib/ui/activity/post_ad/motor/PostAdMotorPage.dart and 5 others)
- Edit ad flow: same category-specific forms pre-filled (lib/ui/activity/post_ad/update/motor/PostAdMotorUpdatePage.dart and 5 others)
- My Ads with tabs: Active
- Pending
- Rejected
- Expired (lib/ui/activity/my_listing/my_listing.dart
- tab_item.dart)
- Favourites list (lib/ui/activity/wish_list/wish_list.dart)
- Chat: conversation list and message screen (lib/ui/activity/chat_message/ChatMessagePage.dart)
- Swap request: offer one of your ads for another (lib/ui/activity/swap_request/SwapRequestPage.dart)
- Job flow: post job
- view applications
- accept candidate with payment (lib/ui/activity/job_accept/JobAccept.dart
- JobAcceptCandidateDetails.dart)
- Job apply: candidate fills profile
- uploads CV
- applies (lib/ui/activity/job_apply/job_apply_page.dart)
- Profile edit
- change password
- delete account (lib/ui/activity/edit_profile/edit_profile.dart)
- Block list
- report ad
- support contact (lib/ui/activity/block_list/block_list_view.dart
- lib/ui/activity/support/SupportPage.dart)
- Push notifications via Firebase (lib/core/services/firebase_service.dart)
- English and Arabic with RTL layout (lib/l10n/app_en.arb
- app_ar.arb
- flutter gen-l10n)
- Google Maps location picker (lib/utils/google_places_picker.dart
- requires GOOGLE_MAPS_API_KEY at build time)
- One configurable server URL (lib/constant/AppConfig.dart
- set with --dart-define=SERVER_URL=... at build time)
REST API (ASP.NET Core, /api/v1/)
- Member registration
- login
- OTP verification
- password reset (Controllers/MemberController.cs Registration
- Login
- VerifyOTP
- ForgotPassword actions)
- JWT bearer token authentication for mobile app (Infrastructure/JwtKeyProvider.cs
- Program.cs AddAuthentication JwtBearer)
- Ad CRUD: create
- update
- delete
- list by category
- search (Controllers/AddPostController.cs AddPost
- UpdatePost
- DeletePost
- GetPostByCategory
- SearchPost actions)
- Ad media upload: photos
- video
- documents (Controllers/PostMediaController.cs UploadPostMedia action
- saves to wwwroot/uploads/)
- Favourites: add
- remove
- list (Controllers/AddPostController.cs AddFavourite
- RemoveFavourite
- GetFavourite actions)
- Chat: send message
- get conversation list
- get messages (Controllers/ConversationController.cs SendMessage
- GetConversationList
- GetMessages actions)
- Swap requests: create
- accept
- reject (Controllers/AddPostController.cs SwapRequest
- AcceptSwapRequest
- RejectSwapRequest actions)
- Job posts: create
- update
- list (Controllers/AddPostController.cs AddJobPost
- UpdateJobPost
- GetJobPosts actions)
- Job applications: apply
- list applications
- accept/reject (Controllers/AddPostController.cs ApplyJob
- GetJobApplications
- AcceptJobApplication actions)
- Boost ad: purchase boost plan
- apply to ad (Controllers/PaymentsController.cs PurchaseBoost action
- calls IPaymentGateway.CreatePaymentIntent)
- Report ad
- block member (Controllers/PostModerationController.cs ReportPost
- BlockMember actions)
- Push notifications: register device token
- send notification (Controllers/NotificationController.cs RegisterDevice
- SendNotification actions)
- Master data: categories
- sub-categories
- attributes
- cities
- countries
- boost plans (Controllers/MasterDataController.cs GetCategories
- GetCities
- GetBoostPlans
- etc.)
- Rate limiting on auth endpoints (5 requests per minute per IP
- Infrastructure/AuthSetup.cs
- [EnableRateLimiting(AuthPolicies.AuthRateLimit)])
- Rate limiting on public ad browsing (30 requests per minute per IP
- [EnableRateLimiting(AuthPolicies.PublicApiRateLimit)])
- Every endpoint requires [Authorize(Policy = AuthPolicies.Member)] unless [AllowAnonymous] (Controllers/BaseController.cs
- SECURITY.md lists every route)
Authentication & Authorization
- Admin panel: cookie authentication (scheme AuthSchemes.Admin
- 12-hour lifetime
- Infrastructure/AdminAuth.cs)
- Website members: cookie authentication (scheme AuthSchemes.Member
- 30-day lifetime
- Infrastructure/MemberAuth.cs)
- Mobile app: JWT bearer tokens (HS256
- 30-day expiry
- Infrastructure/JwtKeyProvider.cs
- secret from JWT_KEY env var)
- Passwords: salted PBKDF2-HMAC-SHA256
- 210
- 000 iterations (Helpers/PasswordHasher.cs HashPassword
- VerifyPassword)
- No default admin password: ADMIN_INITIAL_PASSWORD env var required
- startup fails if missing (Infrastructure/AdminBootstrap.cs)
- No default JWT key: JWT_KEY env var required
- startup fails if missing (Infrastructure/JwtKeyProvider.cs)
- Three admin roles: SuperAdmin (all actions)
- Admin (approvals
- moderation)
- Operation (view-only reports) (Infrastructure/Auth.cs AuthRoles)
- Role enforcement: [Authorize(Roles = AuthRoles.SuperAdmin)] on settings controllers
- [Authorize(Roles = AuthRoles.Managers)] on approval controllers (Areas/Admin/Controllers/)
- Member ownership checks: every update/delete loads the row by key after checking CurrentMemberId == row.MemberId (Infrastructure/Ownership.cs
- DataService/ methods)
- Soft deletes: members
- ads
- admin users set Status = Deleted
- never hard-deleted (DataService/MemberService.cs DeleteMember
- DataService/Admin/PostService.cs DeletePost)
- CSRF protection: SameSiteRequestsAttribute on every admin controller
- rejects requests with Origin/Referer from other sites (Infrastructure/SameSiteRequestsAttribute.cs)
- Rate limiting: 5 req/min on login/registration
- 10 req/min on report/block
- 30 req/min on public ad browsing (Program.cs AddRateLimiter
- [EnableRateLimiting(...)])
Payments (Pluggable Gateway)
- IPaymentGateway interface: CreatePaymentIntent
- ConfirmPayment
- RefundPayment (Services/Payments/IPaymentGateway.cs)
- Demo provider: approves every payment without charging
- for trials (Services/Payments/DemoPaymentGateway.cs
- default in appsettings.json Payments:Provider=Demo)
- Stripe provider: creates PaymentIntent
- confirms
- refunds (Services/Payments/StripePaymentGateway.cs
- requires Stripe:SecretKey and Stripe:PublishableKey in appsettings.json)
- Boost purchase flow: select plan
- call /api/v1/Payments/PurchaseBoost
- get client_secret
- confirm in app (Controllers/PaymentsController.cs PurchaseBoost action)
- Job hire payment: accept candidate
- call /api/v1/Payments/AcceptJobApplication
- get client_secret
- confirm (Controllers/AddPostController.cs AcceptJobApplication action)
- Payment records: Payments table with MemberId
- Amount
- Currency
- Status
- PaymentIntentId (Models/Payment.cs
- DataService/PaymentService.cs)
- No payment keys in source: Stripe keys come from appsettings.json or env vars
- never committed (appsettings.example.json shows placeholders)
Database (SQL Server, Entity Framework 6)
- 33 tables: Members
- Posts
- Categories
- SubCategories
- Attributes
- Cities
- Countries
- Conversations
- Messages
- Favourites
- SwapRequests
- JobPosts
- JobApplications
- Payments
- Notifications
- Banners
- BoostPlans
- PostReports
- BlockedMembers
- Users
- Feedbacks
- TermsConditions
- PrivacyPolicies
- etc. (database/schema.sql)
- Primary keys on every table
- 38 indexes on foreign-key and lookup columns (database/schema.sql summary at top)
- Entity Framework 6 LINQ queries only
- no raw SQL (grep -rnE 'SqlCommand|ExecuteSqlCommand|SqlQuery|FromSql|CommandText' returns nothing
- CLAUDE.md)
- Contexts/SwapioContext.cs: DbContext with DbSet for each table
- OnModelCreating configures relationships
- DataService/ layer: one service class per concern (MemberService
- PostService
- CategoryService
- etc.)
- all methods return models or lists
- Migrations: database/schema.sql creates the schema
- database/seed.sql loads demo data (21 ads
- 3 members
- 5 categories
- 10 cities)
- Docker init: database/init.sh runs schema.sql and seed.sql (if SEED_DEMO_DATA=true) on first start (docker-compose.yml db service)
- Connection string: from appsettings.json ConnectionStrings:DefaultConnection or env var CONNECTION_STRING
- uses swapio_app login with APP_DB_PASSWORD (docker-compose.yml
- HowToSetup.md)
Integrations & Services
- Google Maps: location picker in mobile app (lib/utils/google_places_picker.dart
- requires GOOGLE_MAPS_API_KEY at build time)
- map view on ad details (Flutter APP/README.md)
- Firebase Cloud Messaging: push notifications to mobile app (Services/FirebaseService.cs SendNotification
- lib/core/services/firebase_service.dart
- requires FIREBASE_PROJECT_ID and google-services.json/GoogleService-Info.plist)
- SMTP email: registration confirmation
- password reset (Services/EmailService.cs SendRegistrationResponse
- SendPasswordReset
- requires SMTP_HOST
- SMTP_PORT
- SMTP_USERNAME
- SMTP_PASSWORD in appsettings.json)
- SMS OTP: phone verification (Services/SmsService.cs SendOTP
- requires SMS_API_URL and SMS_AUTH_TOKEN in appsettings.json)
- Stripe: payment processing (Services/Payments/StripePaymentGateway.cs
- requires Stripe:SecretKey and Stripe:PublishableKey)
- File uploads: photos
- video
- documents saved to wwwroot/uploads/ with unique filenames (Controllers/PostMediaController.cs UploadPostMedia
- 500 MB limit in web.config and Program.cs)
- No keys in source: all API keys
- SMTP credentials
- Firebase config come from appsettings.json or env vars
- never committed (appsettings.example.json
- .env.example
- Flutter APP/README.md)
Deployment & DevOps
- Docker Compose: one-command setup with SQL Server
- ASP.NET Core app
- automatic database init (docker-compose.yml
- HowToSetup.md)
- Dockerfile: multi-stage build
- .NET SDK 10.0
- runs on port 8080 (NET Project/IraqShopping/Dockerfile)
- Environment variables: .env.example lists all required and optional settings
- .env holds real secrets (never committed)
- Reproducible builds: packages.lock.json (NuGet)
- pubspec.lock (Flutter)
- global.json (.NET SDK 10.0.101) pin exact versions (NET Project/IraqShopping/packages.lock.json
- Flutter APP/pubspec.lock
- NET Project/global.json)
- No vulnerable packages: dotnet list package --vulnerable --include-transitive returns clean (CHANGELOG.md 2025-01-15 entry)
- Health check: /health endpoint returns 200 OK (Program.cs app.MapHealthChecks)
- Logging: Serilog to console and file
- structured JSON (Program.cs UseSerilog
- appsettings.json Serilog section)
- IIS deployment: web.config with aspNetCore handler
- 500 MB upload limit
- .apk and .webp MIME types (NET Project/IraqShopping/web.config)
- Server install without Docker: HowToSetup.md section 2 lists SQL Server 2019+
- .NET SDK 10.0
- IIS setup steps
Localization & Branding
- English and Arabic UI throughout: website
- admin panel
- mobile app (wwwroot/Areas/Website/src/css/swapio.css .rtl rules
- Flutter APP/lib/l10n/app_en.arb
- app_ar.arb)
- Right-to-left layout: CSS .rtl class on body
- Flutter Directionality widget (wwwroot/Areas/Website/src/css/swapio.css
- lib/ui/widget/swapio/auth_scaffold.dart)
- Brand colors: primary #087FF5
- secondary #FF6B35
- success #10B981
- warning #F59E0B
- danger #EF4444 (docs/BRANDING.md
- wwwroot/Areas/Admin/Content/css/swapio-admin.css CSS variables)
- Fonts: Poppins (headings)
- Inter (UI)
- Cairo (Arabic) (Areas/Admin/Views/Shared/_LayoutAuth.cshtml
- Areas/Website/Views/Shared/_Layout.cshtml)
- Logos: SVG and PNG in docs/logos/
- favicon and app icons in wwwroot/Areas/Admin/Content/assets/images/brand/ and Flutter APP/icons/ (docs/BRANDING.md)
- App icons: generated with flutter_launcher_icons from icons/icon.png (Flutter APP/flutter_launcher_icons.yaml
- Flutter APP/README.md section 7)
- Customization guide: docs/BRANDING.md lists every color variable
- font
- logo file and how to regenerate icons
| Language | Version | Framework | Used for | Share of code |
|---|---|---|---|---|
| Dart | — | — | Mobile app | 34.1% |
| JavaScript | — | — | Front-end | 29.7% |
| CSS | — | — | Styling | 14.5% |
| C# (Razor) | — | — | Web pages | 12.7% |
| C# | — | — | Web, API, admin | 8.1% |
| SQL | — | — | Database | 0.5% |
| HTML | — | — | Front-end | 0.2% |
| SCSS | — | — | Styling | 0.2% |
| Java | — | — | API | 0.1% |
| Shell | — | — | Scripts | 0% |
| Swift | — | — | Mobile app | 0% |
- Primary language
- C# 10 / .NET SDK 10.0
- Framework
- ASP.NET Core 10 + Flutter 3.35
- Database
- SQL Server 2019+
- Authentication
- Cookie (admin + website), JWT bearer (mobile)
- Licence
- Single-site
- Screens
- 47
- Database tables
- 33
- Supported languages
- English, Arabic (RTL)
- Browser support
- Modern browsers (Chrome, Firefox, Safari, Edge)
| Minimum | Recommended | |
|---|---|---|
| CPU | 2 vCPU | 4 vCPU |
| RAM | 4 GB RAM / 20 GB disk | 8 GB RAM / 40 GB disk |
| OS | Linux (Docker) or Windows Server 2019+, .NET SDK 10.0, SQL Server 2019+ | Linux (Docker) or Windows Server 2019+, .NET SDK 10.0, SQL Server 2019+ |
| Est. monthly hosting | $25 | $25 |
cp .env.example .env # set MSSQL_SA_PASSWORD, APP_DB_PASSWORD, ADMIN_INITIAL_PASSWORD, JWT_KEY docker compose up -d --build # site: http://localhost:8080, admin: /admin
Install .NET SDK 10 and SQL Server 2019+, run database/schema.sql, then: cd "NET Project" && dotnet publish IraqShopping/IraqShopping.csproj -c Release -o /var/www/swapio Set the values from appsettings.example.json as environment variables and run it as a systemd service.
Create a .NET 10 web app and an Azure SQL database, run schema.sql, set the connection string and settings in App Service Configuration, then deploy the publish output as a ZIP.
cd "Flutter APP" flutter build apk --release --dart-define=SERVER_URL=https://your-domain.com/ --dart-define=GOOGLE_MAPS_API_KEY=your-key flutter build ipa --release --dart-define=SERVER_URL=https://your-domain.com/ --dart-define=GOOGLE_MAPS_API_KEY=your-key
Quality report
Manually reviewedHow to read the quality report
What this is. Every project on Vibe96 goes through an automated audit of its source code before a reviewer in Dubai checks it by hand. The score is out of 100; 75 is the minimum to be listed, and any single failing check blocks a listing regardless of the score.
- Security
- No real credentials in the code, every data-changing route protected, admin areas role-gated, no SQL built from user input.
- Code structure
- A developer can navigate and extend it: clear module boundaries, no giant files, little copy-paste.
- Docs & completeness
- The setup guide, example config, schema and required files the builder committed to are actually in the archive.
- Dependency health
- Packages pinned, no known critical vulnerabilities, no abandoned libraries in production paths.
- Build & deploy
- A clean machine can restore, build and start it by following the shipped instructions.
Warnings are problems that didn't block the listing; they stay visible here until a later version clears them. The audit reads the code — it does not run it — so always try the live demo before you buy. Lines of code are counted from the same audited archive.
91/ 100
Automated audit score
The automated audit flagged a blocking check · 3 open warnings — listed after a manual review
◷ 3 open warningsWhat to know before you buy
3 non-blocking findings shown publicly: weak default credentials and example files with realistic values present; multiple outdated dependencies, no critical vulnerabilities detected; significant code duplication, oversized files, and mixed concerns reduce maintainability; build reproducible with gaps: missing .net sdk version, incomplete docker setup, unclear flutter config. The seller has been notified; fixes ship in the next version.
Versions & updates
No updates yet. New versions appear here with a changelog.
Buyers receive updates free for 1 year.
What you get
- </>Full source codeThe complete audited source, delivered as a download from your account. No obfuscation.
- ▤DocumentationSetup guide, architecture notes, CLAUDE.md and AGENTS.md.
- ↻One year of updatesEvery new version the builder publishes, free for 12 months.
- ♧30 days of supportInstallation and defect support through Vibe96 tickets.