diff --git a/App/AL/Config/UserSetting/AllowedValues.cs b/App/AL/Config/UserSetting/AllowedValues.cs index 5241a2b..3f011a1 100644 --- a/App/AL/Config/UserSetting/AllowedValues.cs +++ b/App/AL/Config/UserSetting/AllowedValues.cs @@ -6,9 +6,10 @@ public static class AllowedValues { public static Dictionary GetAllowed() => new Dictionary { ["subscription_currency"] = new[] { - "Usd", "BitCoin", "Ethereum", "Erc20Token", "Waves", "WavesToken", "LiteCoin" + "Usd", "BitCoin", "Ethereum", "Waves", "LiteCoin" }, - ["subscription_amount"] = null + ["subscription_amount"] = null, + ["survey_after_register_redirect"] = new[] {"f", "t"}, }; } } \ No newline at end of file diff --git a/App/AL/Controller/Funding/Invoice/InvoiceController.cs b/App/AL/Controller/Funding/Invoice/InvoiceController.cs index 78efdf8..1931e6a 100644 --- a/App/AL/Controller/Funding/Invoice/InvoiceController.cs +++ b/App/AL/Controller/Funding/Invoice/InvoiceController.cs @@ -4,8 +4,8 @@ using App.AL.Validation.Entity; using App.AL.Validation.Funding; using App.DL.Enum; -using App.DL.Model.User; using App.DL.Repository.Funding; +using App.DL.Repository.User; using App.PL.Transformer.Funding; using Micron.AL.Validation.Basic; using Micron.AL.Validation.Db; @@ -23,7 +23,7 @@ public sealed class InvoiceController : BaseController { public InvoiceController() { Post("/api/v1/invoice/new", _ => { - var me = User.Find(CurrentRequest.UserId); + var me = DL.Model.User.User.Find(CurrentRequest.UserId); var errors = ValidationProcessor.Process(Request, new IValidatorRule[] { new ShouldHaveParameters(new[] {"entity_guid", "entity_type", "amount", "currency_type"}), @@ -56,7 +56,7 @@ public InvoiceController() { }); Get("/api/v1/me/invoice/get", _ => { - var me = User.Find(CurrentRequest.UserId); + var me = UserRepository.Find(CurrentRequest.UserId); var errors = ValidationProcessor.Process(Request, new IValidatorRule[] { new ShouldHaveParameters(new[] {"invoice_guid"}), @@ -73,7 +73,7 @@ public InvoiceController() { }); Get("/api/v1/me/invoices/finished", _ => { - var me = User.Find(CurrentRequest.UserId); + var me = UserRepository.Find(CurrentRequest.UserId); var invoices = DL.Model.Funding.Invoice.GetForUserByStatuses(me, new [] { InvoiceStatus.Confirmed, InvoiceStatus.Failed, InvoiceStatus.Done @@ -83,7 +83,7 @@ public InvoiceController() { }); Get("/api/v1/me/invoices/active", _ => { - var me = User.Find(CurrentRequest.UserId); + var me = UserRepository.Find(CurrentRequest.UserId); var invoices = DL.Model.Funding.Invoice.GetActiveForUser(me, 25); @@ -91,7 +91,7 @@ public InvoiceController() { }); Patch("/api/v1/me/invoice/status/update", _ => { - var me = User.Find(CurrentRequest.UserId); + var me = UserRepository.Find(CurrentRequest.UserId); var errors = ValidationProcessor.Process(Request, new IValidatorRule[] { new ShouldHaveParameters(new[] {"invoice_guid", "status"}), diff --git a/App/AL/Controller/Project/Post/ProjectCrudController.cs b/App/AL/Controller/Project/Post/ProjectCrudController.cs new file mode 100644 index 0000000..e62c518 --- /dev/null +++ b/App/AL/Controller/Project/Post/ProjectCrudController.cs @@ -0,0 +1,62 @@ +using App.AL.Validation.Permission; +using App.DL.Enum; +using App.DL.Model.Project.Post; +using App.DL.Repository.Project; +using App.DL.Repository.User; +using App.PL.Transformer.Project.Post; +using Micron.AL.Validation.Basic; +using Micron.AL.Validation.Db; +using Micron.DL.Middleware; +using Micron.DL.Middleware.Auth; +using Micron.DL.Module.Controller; +using Micron.DL.Module.Http; +using Micron.DL.Module.Validator; +using Nancy; + +namespace App.AL.Controller.Project.Post { + public class ProjectCrudController : BaseController { + protected override IMiddleware[] Middleware() => new IMiddleware[] { + new JwtMiddleware(), + }; + + public ProjectCrudController() { + Post("/api/v1/project/post/new", _ => { + var me = UserRepository.Find(CurrentRequest.UserId); + var project = ProjectRepository.FindByGuid(GetRequestStr("project_guid")); + if (project == null) return HttpResponse.Error(HttpStatusCode.NotFound, "Project not found"); + + var errors = ValidationProcessor.Process(Request, new IValidatorRule[] { + new ShouldHaveParameters(new[] {"project_guid", "title", "content"}), + new ExistsInTable("project_guid", "projects", "guid"), + new HasPermission(me, project.id, EntityType.Project), + }, true); + if (errors.Count > 0) return HttpResponse.Errors(errors); + + var post = ProjectPost.Create( + project, GetRequestStr("title"), GetRequestStr("content") + ); + + return HttpResponse.Item( + "post", new ProjectPostTransformer().Transform(post), HttpStatusCode.Created + ); + }); + + Delete("/api/v1/project/post/delete", _ => { + var post = ProjectPost.FindBy("guid", GetRequestStr("post_guid")); + if (post == null) return HttpResponse.Error(HttpStatusCode.NotFound, "Post not found"); + + var me = UserRepository.Find(CurrentRequest.UserId); + + var errors = ValidationProcessor.Process(Request, new IValidatorRule[] { + new ShouldHaveParameters(new[] {"post_guid"}), + new HasPermission(me, post.project_id, EntityType.Project), + }, true); + if (errors.Count > 0) return HttpResponse.Errors(errors); + + post.Delete(); + + return HttpResponse.Item("post", new ProjectPostTransformer().Transform(post)); + }); + } + } +} \ No newline at end of file diff --git a/App/AL/Controller/Project/Post/ProjectPostsController.cs b/App/AL/Controller/Project/Post/ProjectPostsController.cs new file mode 100644 index 0000000..bf6df45 --- /dev/null +++ b/App/AL/Controller/Project/Post/ProjectPostsController.cs @@ -0,0 +1,33 @@ +using App.DL.Model.Project.Post; +using App.DL.Repository.Project; +using App.PL.Transformer.Project.Post; +using Micron.AL.Validation.Db; +using Micron.DL.Middleware; +using Micron.DL.Module.Controller; +using Micron.DL.Module.Http; +using Micron.DL.Module.Validator; + +namespace App.AL.Controller.Project.Post { + public class ProjectPostsController : BaseController { + protected override IMiddleware[] Middleware() => new IMiddleware[] {}; + + public ProjectPostsController() { + Get("/api/v1/all_projects/posts/latest/get", _ => { + return HttpResponse.Item( + "posts", new ProjectPostTransformer().Many(ProjectPost.Latest()) + ); + }); + + Get("/api/v1/project/posts/get", _ => { + var errors = ValidationProcessor.Process(Request, new IValidatorRule[] { + new ExistsInTable("project_guid", "projects", "guid"), + }); + if (errors.Count > 0) return HttpResponse.Errors(errors); + + var project = ProjectRepository.FindByGuid(GetRequestStr("project_guid")); + + return HttpResponse.Item("posts", new ProjectPostTransformer().Many(project.Posts())); + }); + } + } +} \ No newline at end of file diff --git a/App/AL/Controller/Repo/RepoController.cs b/App/AL/Controller/Repo/RepoController.cs index 78ecf0f..3838259 100644 --- a/App/AL/Controller/Repo/RepoController.cs +++ b/App/AL/Controller/Repo/RepoController.cs @@ -1,3 +1,8 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using App.DL.Enum; using App.DL.Repository.Repo; using App.PL.Transformer.Repo; using Micron.AL.Validation.Db; @@ -5,22 +10,60 @@ using Micron.DL.Module.Controller; using Micron.DL.Module.Http; using Micron.DL.Module.Validator; +using Newtonsoft.Json.Linq; +using Sentry; +using YamlDotNet.Serialization; namespace App.AL.Controller.Repo { public sealed class RepoController : BaseController { protected override IMiddleware[] Middleware() => new IMiddleware[] { }; - + public RepoController() { Get("/api/v1/repository/get", _ => { var errors = ValidationProcessor.Process(Request, new IValidatorRule[] { new ExistsInTable("repo_guid", "repositories", "guid"), }); if (errors.Count > 0) return HttpResponse.Errors(errors); - + return HttpResponse.Item("repository", new RepoTransformer().Transform( RepoRepository.FindByGuid((string) Request.Query["repo_guid"]) )); }); + + Get("/api/v1/repository/meta/get", _ => { + var errors = ValidationProcessor.Process(Request, new IValidatorRule[] { + new ExistsInTable("repo_guid", "repositories", "guid"), + }); + if (errors.Count > 0) return HttpResponse.Errors(errors); + + var sponsorLinks = new JObject(); + + var repo = RepoRepository.FindByGuid((string) Request.Query["repo_guid"]); + + if (repo.service_type == RepoServiceType.GitHub) { + try { + var splitUrl = repo.repo_url.Split("/"); + var response = new HttpClient().GetAsync( + $"https://raw.githubusercontent.com/{splitUrl[3]}/{splitUrl[4]}/master/.github/FUNDING.yml" + ).Result.Content.ReadAsStringAsync().Result; + var yamlObject = (Dictionary) new DeserializerBuilder().Build() + .Deserialize(new StringReader(response)); + sponsorLinks["github"] = yamlObject["github"]?.ToString(); + sponsorLinks["patreon"] = yamlObject["patreon"]?.ToString(); + sponsorLinks["open_collective"] = yamlObject["open_collective"]?.ToString(); + } + catch (Exception e) { + SentrySdk.CaptureException(e); + } + } + + return HttpResponse.Data(new JObject() { + ["repository"] = new RepoTransformer().Transform(repo) + ["meta"] = new JObject() { + ["sponsor_links"] = sponsorLinks + } + }); + }); } } } \ No newline at end of file diff --git a/App/AL/Controller/User/Badge/BadgeController.cs b/App/AL/Controller/User/Badge/BadgeController.cs new file mode 100644 index 0000000..94f4755 --- /dev/null +++ b/App/AL/Controller/User/Badge/BadgeController.cs @@ -0,0 +1,28 @@ +using App.DL.Repository.User; +using App.PL.Transformer.User.Badge; +using Micron.AL.Validation.Basic; +using Micron.AL.Validation.Db; +using Micron.DL.Middleware; +using Micron.DL.Module.Controller; +using Micron.DL.Module.Http; +using Micron.DL.Module.Validator; + +namespace App.AL.Controller.User.Badge { + public class BadgeController : BaseController { + protected override IMiddleware[] Middleware() => new IMiddleware[] { }; + + public BadgeController() { + Get("/api/v1/user/badges/get", _ => { + var errors = ValidationProcessor.Process(Request, new IValidatorRule[] { + new ShouldHaveParameters(new[] {"user_guid"}), + new ExistsInTable("user_guid", "users", "guid"), + }, true); + if (errors.Count > 0) return HttpResponse.Errors(errors); + + var user = UserRepository.FindByGuid(GetRequestStr("user_guid")); + + return HttpResponse.Item("badges", new UserBadgeTransformer().Many(user.Badges())); + }); + } + } +} \ No newline at end of file diff --git a/App/AL/Controller/Settings/MySettingsController.cs b/App/AL/Controller/User/Settings/MySettingsController.cs similarity index 98% rename from App/AL/Controller/Settings/MySettingsController.cs rename to App/AL/Controller/User/Settings/MySettingsController.cs index 68fa380..d8b5180 100644 --- a/App/AL/Controller/Settings/MySettingsController.cs +++ b/App/AL/Controller/User/Settings/MySettingsController.cs @@ -12,7 +12,7 @@ using Micron.DL.Module.Validator; using Nancy; -namespace App.AL.Controller.Settings { +namespace App.AL.Controller.User.Settings { public class MySettingsController : BaseController { protected override IMiddleware[] Middleware() => new IMiddleware[] { new JwtMiddleware(), diff --git a/App/AL/Middleware/Schedule/ScheduleAuth.cs b/App/AL/Middleware/Schedule/ScheduleAuth.cs new file mode 100644 index 0000000..bd84a94 --- /dev/null +++ b/App/AL/Middleware/Schedule/ScheduleAuth.cs @@ -0,0 +1,20 @@ +using Micron.DL.Middleware; +using Micron.DL.Module.Config; +using Micron.DL.Module.Http; +using Nancy; + +namespace App.AL.Middleware.Schedule { + public class ScheduleAuth : IMiddleware { + public ProcessedRequest Process(ProcessedRequest request) { + var scheduleToken = AppConfig.GetConfiguration("auth:schedule:token"); + + if ( + string.IsNullOrEmpty(scheduleToken) || scheduleToken != request.GetRequestStr("schedule_token") + ) { + request.AddError(new HttpError(HttpStatusCode.Unauthorized, "Schedule token is invalid")); + } + + return request; + } + } +} \ No newline at end of file diff --git a/App/AL/Schedule/Project/Post/SyncReleases.cs b/App/AL/Schedule/Project/Post/SyncReleases.cs new file mode 100644 index 0000000..081c014 --- /dev/null +++ b/App/AL/Schedule/Project/Post/SyncReleases.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using App.AL.Middleware.Schedule; +using App.DL.Enum; +using App.DL.Model.Project.Post; +using App.DL.Model.Repo; +using Micron.DL.Middleware; +using Micron.DL.Module.Config; +using Micron.DL.Module.Controller; +using Micron.DL.Module.Http; +using Newtonsoft.Json.Linq; +using Octokit; +using Sentry; + +namespace App.AL.Schedule.Project.Post { + public class SyncReleases : BaseController { + protected override IMiddleware[] Middleware() => new IMiddleware[] { + new ScheduleAuth(), + }; + + public SyncReleases() { + Post("/api/v1/schedule/project/sync_releases/start", _ => { + Task.Run(() => { + var githubClient = new GitHubClient(new ProductHeaderValue("GitCom")); + var githubToken = AppConfig.GetConfiguration("auth:external:github:token"); + if (githubToken != null) githubClient.Credentials = new Credentials(githubToken); + + int pageIndex = 1; + var repos = Repo.Paginate(pageIndex); + + while (repos.Length > 0) { + foreach (var repo in repos) { + try { + if (repo.service_type != RepoServiceType.GitHub) continue; + var splitUrl = repo.repo_url.Split("/"); + IEnumerable releases; + try { + releases = githubClient.Repository.Release.GetAll( + splitUrl[3], splitUrl[4] + ).Result.OrderBy(x => x.Id); + } + catch (Exception e) { + continue; // ignored + } + + foreach (var release in releases) { + if (release.Body.Length < 100) continue; + + var existingPost = ProjectPost.FindBy("origin_id", release.Id.ToString()); + if (existingPost != null) continue; + + var post = ProjectPost.Create( + repo.Project(), $"Released {release.Name}", release.Body + ); + post.UpdateCol("origin_id", release.Id.ToString()); + post.UpdateCol( + "created_at", release.PublishedAt.Value.ToUnixTimeSeconds().ToString() + ); + } + } + catch (Exception e) { + SentrySdk.CaptureException(e); + } + } + + ++pageIndex; + repos = Repo.Paginate(pageIndex); + } + }); + return HttpResponse.Data(new JObject()); + }); + } + } +} \ No newline at end of file diff --git a/App/AL/Tasks/Project/ProjectSetUp.cs b/App/AL/Tasks/Project/ProjectSetUp.cs index b3efd80..82b6c14 100644 --- a/App/AL/Tasks/Project/ProjectSetUp.cs +++ b/App/AL/Tasks/Project/ProjectSetUp.cs @@ -5,6 +5,7 @@ using App.DL.Repository.BoardColumn; using App.DL.Repository.Card; using App.DL.Repository.ProjectTeamMember; +using App.DL.Repository.UserLibrary; namespace App.AL.Tasks.Project { public static class ProjectSetUp { @@ -22,8 +23,9 @@ public static void Run(DL.Model.Project.Project project, User creator) { BoardColumnRepository.CreateAndGet("In progress", board, 2); BoardColumnRepository.CreateAndGet("Done", board, 3); CardRepository.CreateAndGet( - "Some task", DefaultCardDescription, 1, todoColumn, creator + "Example card", DefaultCardDescription, 1, todoColumn, creator ); + UserLibraryItemRepository.FindOrCreate(project.Creator(), project); } } } \ No newline at end of file diff --git a/App/AL/Utils/External/GitHub/GitHubRepositoriesUtils.cs b/App/AL/Utils/External/GitHub/GitHubRepositoriesUtils.cs index 02f1d93..903940c 100644 --- a/App/AL/Utils/External/GitHub/GitHubRepositoriesUtils.cs +++ b/App/AL/Utils/External/GitHub/GitHubRepositoriesUtils.cs @@ -16,7 +16,7 @@ public static class GitHubRepositoriesUtils { public const string GithubApiHost = "https://api.github.com/"; private static GitHubClient GetClient() { - return new GitHubClient(new ProductHeaderValue("SupportHub")); + return new GitHubClient(new ProductHeaderValue("GitCom")); } public static ExternalRepo[] GetUserRepositories(User user) { diff --git a/App/App.csproj b/App/App.csproj index 4e1bcf3..0f7e007 100644 --- a/App/App.csproj +++ b/App/App.csproj @@ -5,7 +5,7 @@ netcoreapp2.2 8 enable - 0.17.1 + 0.18.0 @@ -13,9 +13,10 @@ - + + diff --git a/App/DL/Model/Project/Post/ProjectPost.cs b/App/DL/Model/Project/Post/ProjectPost.cs new file mode 100644 index 0000000..7526281 --- /dev/null +++ b/App/DL/Model/Project/Post/ProjectPost.cs @@ -0,0 +1,64 @@ +using System; +using System.Linq; +using App.DL.Repository.Project; +using Dapper; + +namespace App.DL.Model.Project.Post { + public class ProjectPost : Micron.DL.Model.Model { + public int id; + + public string guid; + + public int project_id; + + public string title; + + public string content; + + public DateTime created_at; + + public DateTime updated_at; + + public static ProjectPost Find(int id) + => Connection().Query( + "SELECT * FROM project_posts WHERE id = @id LIMIT 1", new {id} + ).FirstOrDefault(); + + public static ProjectPost FindBy(string col, string val) + => Connection().Query( + $"SELECT * FROM project_posts WHERE {col} = @val LIMIT 1", new {val} + ).FirstOrDefault(); + + public static ProjectPost[] Get(Project project) + => Connection().Query( + "SELECT * FROM project_posts WHERE project_id = @project_id LIMIT 10", new {project_id = project.id} + ).ToArray(); + + public static ProjectPost[] Latest() => Connection() + .Query("SELECT * FROM project_posts ORDER BY id DESC LIMIT 10") + .ToArray(); + + public static ProjectPost Create(Project project, string title, string content) { + return Find(ExecuteScalarInt( + @"INSERT INTO project_posts(guid, project_id, title, content, updated_at) + VALUES (@guid, @project_id, @title, @content, CURRENT_TIMESTAMP); + SELECT currval('project_posts_id_seq');" + , new { + guid = Guid.NewGuid().ToString(), project_id = project.id, title, content + } + )); + } + + public ProjectPost UpdateCol(string col, string val) { + ExecuteSql( + $"UPDATE project_posts SET {col} = @val, updated_at = CURRENT_TIMESTAMP WHERE id = @id", + new {val, id} + ); + return this; + } + + public void Delete() => ExecuteScalarInt("DELETE FROM project_posts WHERE id = @id", new {id}); + + public Project Project() => ProjectRepository.Find(project_id); + } +} \ No newline at end of file diff --git a/App/DL/Model/Project/Project.cs b/App/DL/Model/Project/Project.cs index e1e4eb9..d840410 100644 --- a/App/DL/Model/Project/Project.cs +++ b/App/DL/Model/Project/Project.cs @@ -11,6 +11,7 @@ using App.DL.Repository.Project; using App.DL.Repository.Product; using App.DL.Model.Product; +using App.DL.Model.Project.Post; // ReSharper disable InconsistentNaming @@ -54,12 +55,12 @@ public static Project FindBy(string col, int val) public static Project[] GetBy(string col, string val) => Connection().Query( - $"SELECT * FROM projects WHERE {col} = @val LIMIT 1", new {val} + $"SELECT * FROM projects WHERE {col} = @val LIMIT 50", new {val} ).ToArray(); public static Project[] GetBy(string col, int val) => Connection().Query( - $"SELECT * FROM projects WHERE {col} = @val LIMIT 1", new {val} + $"SELECT * FROM projects WHERE {col} = @val LIMIT 50", new {val} ).ToArray(); public static Project FindRandom() @@ -136,6 +137,8 @@ public bool InLibrary(UserModel user) public int StarsCount() => ExecuteScalarInt("SELECT COUNT(*) FROM user_projects_library WHERE project_id = @id", new {id}); + public ProjectPost[] Posts() => ProjectPost.Get(this); + public void Delete() => ExecuteScalarInt("DELETE FROM projects WHERE id = @id", new {id}); } } \ No newline at end of file diff --git a/App/DL/Model/Repo/Repo.cs b/App/DL/Model/Repo/Repo.cs index a94e558..4a6f0ef 100644 --- a/App/DL/Model/Repo/Repo.cs +++ b/App/DL/Model/Repo/Repo.cs @@ -52,6 +52,12 @@ public static Repo Find(string originId, RepoServiceType type) new {origin_id = originId} ).FirstOrDefault(); + public static Repo[] Paginate(int page, int size = 20) + => Connection().Query( + "SELECT * FROM repositories OFFSET @offset LIMIT @size", + new {offset = ((page-1) * size), size} + ).ToArray(); + public static int Create( UserModel creator, string title, string repoUrl, RepoServiceType serviceType, string originId = "" ) { diff --git a/App/DL/Model/User/Badge/UserBadge.cs b/App/DL/Model/User/Badge/UserBadge.cs new file mode 100644 index 0000000..458e27e --- /dev/null +++ b/App/DL/Model/User/Badge/UserBadge.cs @@ -0,0 +1,56 @@ +using System; +using System.Linq; +using App.DL.Repository.User; +using Dapper; + +namespace App.DL.Model.User.Badge { + public class UserBadge : Micron.DL.Model.Model { + public int id; + + public string guid; + + public int user_id; + + public string badge; + + public DateTime created_at; + + public static UserBadge Find(int id) + => Connection().Query( + "SELECT * FROM user_badges WHERE id = @id LIMIT 1", new {id} + ).FirstOrDefault(); + + public static UserBadge FindBy(string col, string val) + => Connection().Query( + $"SELECT * FROM user_badges WHERE {col} = @val LIMIT 1", new {val} + ).FirstOrDefault(); + + public static UserBadge[] Get(User user) + => Connection().Query( + "SELECT * FROM user_badges WHERE user_id = @user_id", new {user_id = user.id} + ).ToArray(); + + public static UserBadge Create(User user, string badge) { + return Find(ExecuteScalarInt( + @"INSERT INTO user_badges(guid, user_id, badge) + VALUES (@guid, @user_id, @badge); + SELECT currval('user_badges_id_seq');" + , new { + guid = Guid.NewGuid().ToString(), user_id = user.id, badge + } + )); + } + + public UserBadge UpdateCol(string col, string val) { + ExecuteSql( + $"UPDATE user_badges SET {col} = @val WHERE id = @id", + new {val, id} + ); + return this; + } + + public void Delete() => ExecuteScalarInt("DELETE FROM user_badges WHERE id = @id", new {id}); + + public User User() => UserRepository.Find(user_id); + } +} \ No newline at end of file diff --git a/App/DL/Model/User/User.cs b/App/DL/Model/User/User.cs index ade8b48..a8d29b1 100644 --- a/App/DL/Model/User/User.cs +++ b/App/DL/Model/User/User.cs @@ -3,6 +3,7 @@ using System.Net.Mail; using App.DL.Enum; using App.DL.Model.Auth; +using App.DL.Model.User.Badge; using App.DL.Repository.Auth; using App.DL.Repository.Project; using Micron.DL.Module.Crypto; @@ -68,5 +69,7 @@ public ServiceAccessToken ServiceAccessToken(ServiceType serviceType) => ServiceAccessTokenRepository.Find(this, serviceType); public Project.Project[] Projects() => ProjectRepository.GetBy("creator_id", id); + + public UserBadge[] Badges() => UserBadge.Get(this); } } \ No newline at end of file diff --git a/App/DL/Repository/User/UserRepository.cs b/App/DL/Repository/User/UserRepository.cs index a8106e8..72d8446 100644 --- a/App/DL/Repository/User/UserRepository.cs +++ b/App/DL/Repository/User/UserRepository.cs @@ -1,3 +1,4 @@ +using App.DL.Model.User.Badge; using App.DL.Module.Cache; using App.DL.Repository.User.Referral; using Micron.DL.Module.Misc; @@ -54,6 +55,8 @@ public static UserModel FindOrCreateByEmailAndLogin( user ??= Create(email, login, password); + UserBadge.Create(user, "Early adopter"); + if (referral != null) UserReferralRepository.Create(user, referral); return user; diff --git a/App/PL/Transformer/Project/Post/ProjectPostTransformer.cs b/App/PL/Transformer/Project/Post/ProjectPostTransformer.cs new file mode 100644 index 0000000..da83b23 --- /dev/null +++ b/App/PL/Transformer/Project/Post/ProjectPostTransformer.cs @@ -0,0 +1,20 @@ +using App.DL.Model.Project.Post; +using Micron.PL.Transformer; +using Newtonsoft.Json.Linq; + +namespace App.PL.Transformer.Project.Post { + public class ProjectPostTransformer : BaseTransformer { + public override JObject Transform(object obj) { + var item = (ProjectPost) obj; + var result = new JObject { + ["guid"] = item.guid, + ["title"] = item.title, + ["project_guid"] = item.Project().guid, + ["content"] = item.content, + ["created_at"] = item.created_at, + ["updated_at"] = item.updated_at + }; + return result; + } + } +} \ No newline at end of file diff --git a/App/PL/Transformer/User/Badge/UserBadgeTransformer.cs b/App/PL/Transformer/User/Badge/UserBadgeTransformer.cs new file mode 100644 index 0000000..9a0b1b3 --- /dev/null +++ b/App/PL/Transformer/User/Badge/UserBadgeTransformer.cs @@ -0,0 +1,17 @@ +using App.DL.Model.User.Badge; +using Micron.PL.Transformer; +using Newtonsoft.Json.Linq; + +namespace App.PL.Transformer.User.Badge { + public class UserBadgeTransformer : BaseTransformer { + public override JObject Transform(object obj) { + var item = (UserBadge) obj; + return new JObject() { + ["guid"] = item.guid, + ["user_guid"] = item.User().id, + ["badge"] = item.badge, + ["created_at"] = item.created_at.ToString("d"), + }; + } + } +} \ No newline at end of file diff --git a/App/PL/Transformer/Setting/UserSettingTransformer.cs b/App/PL/Transformer/User/Setting/UserSettingTransformer.cs similarity index 100% rename from App/PL/Transformer/Setting/UserSettingTransformer.cs rename to App/PL/Transformer/User/Setting/UserSettingTransformer.cs diff --git a/App/PL/Transformer/UserLibrary/UserLibraryItemTransformer.cs b/App/PL/Transformer/User/UserLibrary/UserLibraryItemTransformer.cs similarity index 100% rename from App/PL/Transformer/UserLibrary/UserLibraryItemTransformer.cs rename to App/PL/Transformer/User/UserLibrary/UserLibraryItemTransformer.cs diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index f72e559..c130ad2 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/migrations/db/migrations/20200121113243_create_project_posts_table.php b/migrations/db/migrations/20200121113243_create_project_posts_table.php new file mode 100644 index 0000000..96e450a --- /dev/null +++ b/migrations/db/migrations/20200121113243_create_project_posts_table.php @@ -0,0 +1,24 @@ +table('project_posts'); + $table + ->addColumn('guid', 'string') + ->addColumn('project_id', 'integer', ['signed' => false, 'null' => false]) + ->addColumn('title', 'text') + ->addColumn('content', 'text') + + ->addForeignKey('project_id', 'projects', 'id', ['delete'=> 'CASCADE', 'update'=> 'CASCADE']) + + ->addTimestamps() + + ->addIndex(['guid'], ['unique' => true]) + + ->create(); + } +} diff --git a/migrations/db/migrations/20200125170233_alter_project_posts_add_origin_id.php b/migrations/db/migrations/20200125170233_alter_project_posts_add_origin_id.php new file mode 100644 index 0000000..663a18a --- /dev/null +++ b/migrations/db/migrations/20200125170233_alter_project_posts_add_origin_id.php @@ -0,0 +1,14 @@ +table('project_posts'); + $table->addColumn('origin_id', 'string', ['null' => true]) + ->save(); + } +} diff --git a/migrations/db/migrations/20200126090236_alter_user_badges_add_timetamps.php b/migrations/db/migrations/20200126090236_alter_user_badges_add_timetamps.php new file mode 100644 index 0000000..fcb837b --- /dev/null +++ b/migrations/db/migrations/20200126090236_alter_user_badges_add_timetamps.php @@ -0,0 +1,14 @@ +table('user_badges'); + $table->addColumn('created_at', 'timestamp', ['default' => 'CURRENT_TIMESTAMP']) + ->save(); + } +}