لینکهای مفید برای شرکت در مسابقه:
در طول مسابقه، میتوانید سوالهای خود را از قسمت «سؤال بپرسید» مطرح کنید.
تیم فنی اسنپ قصد دارد تا سیستم جدیدی برای مدیریت دستاوردهای کاربران و دادن امتیاز به آنها با بهرهگیری از gamification پیادهسازی کند، اما به دلیل درخواست این تیم برای جذب نیروی فنی، آنها این تسک را به برخی از افرادی سپردهاند که در مرحلهی اول مصاحبهی اسنپ قبول شدهاند. مهدی که سرش شلوغ است، اما میخواهد در اسنپ استخدام شود، از شما میخواهد تا این تسک را برایش انجام دهید. نسخهی اولیهی این سیستم قرار است یک API ساده باشد.
پروژهی اولیه را از این لینک دانلود کنید. ساختار فایلهای پروژه بهصورت زیر است:
در این پروژه از پایگاه دادهی PostgreSQL استفاده شده است. برنامه شامل جداول زیر است:
users
):نام ستون | نوع | تعریف | ملاحضات |
---|---|---|---|
id |
BIGSERIAL |
شناسهی کاربر | PRIMARY KEY |
name |
VARCHAR(255) |
نام | |
phone |
VARCHAR(255) |
شماره تلفن |
achievements
):نام ستون | نوع | تعریف | ملاحظات |
---|---|---|---|
id |
BIGSERIAL |
شناسهی دستاورد | PRIMARY KEY |
title |
VARCHAR(255) |
عنوان دستاورد |
user_achievements
):نام ستون | نوع | تعریف |
---|---|---|
user_id |
BIGINT |
شناسهی کاربر |
achievement_id |
BIGINT |
شناسهی دستاورد |
دسترسی به پایگاه داده از طریق تابع db.GetConnection
صورت میگیرد که به شکل singleton پیادهسازی شده است.
یک map[int](func(int) bool)
به شکل singleton در برنامه تعریف شده که از طریق تابع achievements.GetMap
قابل دسترسی است. این مپ، نگاشتی از شناسهی دستاوردها به توابعی است که با دریافت شناسهی یک کاربر، مشخص میکنند که آیا آن دستاورد توسط کاربر کسب شده است یا خیر.
نسخهی اولیهی این API شامل روتهای زیر است:
/is_achieved
: این روت به تابع handlers.IsAchieved
مپ شده است که با دریافت یک user_id
و یک achievement_id
از query string، مشخص میکند که آیا دستاورد توسط کاربر ذکرشده کسب شده است یا خیر.user_id
مقداردهی نشده باشد، کد پاسخ باید 400
و بدنهی پاسخ باید {"error": "no user id provided"}
باشد.user_id
مقداردهی شده باشد، اما پارامتر achievement_id
مقداردهی نشده باشد، کد پاسخ باید 400
و بدنهی پاسخ باید {"error": "no achievement id provided"}
باشد.user_id
عددی نباشد، کد پاسخ باید 400
و بدنهی پاسخ باید {"error": "invalid user id"}
باشد.user_id
عددی باشد، اما مقدار پارامتر achievement_id
عددی نباشد، کد پاسخ باید 400
و بدنهی پاسخ باید {"error": "invalid achievement id"}
باشد.user_id
در جدول users
موجود نباشد، کد پاسخ باید 404
و بدنهی پاسخ باید {"error": "user not found"}
باشد.user_id
در جدول users
موجود باشد، اما دستاوردی با شناسهی achievement_id
در جدول achievements
موجود نباشد، کد پاسخ باید 404
و بدنهی پاسخ باید {"error": "achievement not found"}
باشد.200
و بدنهی پاسخ باید {"is_achieved": true}
یا {"is_achieved": false}
باشد (بسته به این که کاربر دستاورد را کسب کرده است یا خیر)./get_achievements
: این روت به تابع handlers.GetAchievements
مپ شده است که با دریافت یک user_id
از query string، لیست دستاوردهای کاربر را برمیگرداند.user_id
مقداردهی نشده باشد، کد پاسخ باید 400
و بدنهی پاسخ باید {"error": "no user id provided"}
باشد.user_id
عددی نباشد، کد پاسخ باید 400
و بدنهی پاسخ باید {"error": "invalid user id"}
باشد.user_id
در جدول users
موجود نباشد، کد پاسخ باید 404
و بدنهی پاسخ باید {"error": "user not found"}
باشد.200
و بدنهی پاسخ باید به فرم {"achievements": ["achievement 1 name", "achievement 2 name"]}
باشد (نام دستاوردها باید بهترتیب صعودی شناسهشان باشد)./refresh_achievements
: این روت به تابع handlers.RefreshAchievements
مپ شده است که با دریافت یک user_id
از query_string، لیست دستاوردهای کاربر را بهروز میکند. در واقع، دستاوردهایی که تاکنون توسط کاربر کسب نشدهاند باید مجدداً بررسی شوند و در صورتی که دستاورد جدیدی کسب شده بود، در جدول user_achievements
درج شود./get_achievements
باشد، با این تفاوت که دستاوردهای کسبنشده مجدداً بررسی میشوند.توجه: مقدار هدر Content-Type
در پاسخ همهی درخواستها باید برابر با application/json
قرار داده شود.
پس از پیادهسازی برنامه، یک فایل زیپ آپلود کنید که وقتی آن را باز میکنیم، با ساختار زیر مواجه شویم: