GithubHelp home page GithubHelp logo

coderplanets / coderplanets_server Goto Github PK

View Code? Open in Web Editor NEW
220.0 220.0 21.0 428.93 MB

coderplanets.com API(GraphQL) server, build with elixir, phoenix, absinthe

Home Page: https://api.coderplanets.com/graphiql

License: Apache License 2.0

Elixir 98.92% Shell 0.09% HTML 0.02% JavaScript 0.02% Dockerfile 0.05% Makefile 0.51% CSS 0.40% Euphoria 0.01%

coderplanets_server's People

Contributors

caicaishmily avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar mydearxym avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

coderplanets_server's Issues

support read=false on paged contents query

when query read=true, i can use:

read == true ->
   queryable
   |> join(:inner, [content, f, c], viewers in assoc(content, :viewers))
   |> where([content, f, c, viewers], viewers.user_id == ^user.id)

but came to read=false, this is not work as except

read == true ->
   queryable
   |> join(:inner, [content, f, c], viewers in assoc(content, :viewers))
   |> where([content, f, c, viewers], viewers.user_id != ^user.id)

because the viewers assoc only have records of viewed user, the unviewed user is not in that table
left_join is not working either, need help...

should have article inner logger

handle situation like

  • x-user lock/unlock conversion(comments) of a article when the problem solved or other reason
  • article edit history with diff UI, just like the git system
  • etc ..

a possible inner logger table for post would be like this:

post_loggers:

post_id user_id action old_content new_content reason
xx xx lock .. .. solved
xx xx edit old blabla new blabla ...

use macro to reduce boilerplate code

some code like

field :paged_posts, :paged_posts do
    arg(:filter, non_null(:paged_article_filter))
    
    middleware(M.PageSizeProof)
    resolve(&Resolvers.CMS.paged_posts/3)
    middleware(M.FormatPagination)
end

some file like
page_post_test

has lots of boilerplate code with job, video, repo ... should use macro to reduce it

forum robot system

should have robot system to do the chores, like(not limit to):

  1. set a cron to scan every month's posts/jobs/..., once the favorited count > threshold value, then recommend it to the home community
  2. block user / post / .. 's recover
  3. radar scan -- use tools like RSSHub etc to aggregate cool staff for ever communities
  4. ...

add throttle middle to publish contents

to avoid massive trash / unrelated content(post, job, ... etc) publish in short time.
let's set a time limit in a row of publish articles.

details

add a table to statistics module to log the user publish behavior , then use a middleware to diff time between now and latest publish time.

why use post method as "get" in GraphQL ?

  1. as mentioned in Absinthe doc

Due to varying limits on the maximum size of URLs, we recommend using one of the POST options below instead, putting the query into the body of the request.

  1. phoenix 1.5+ requires plug > 1.10, which treat all the GET parameter values as strings, it will break the workflow, see elixir-plug/plug#1006

attachment support

article-like content will freeze after a day / week, if owner want to update after the limit date, the updated content can only go to the attachment field which will display "update/更新" on the front-end page.

article lock/unlock feature

when a article-like content in follow situations:

  • the problem mentioned in article is solved
  • has published very long time, the content has no value
  • has no point, but not to the delete level
  • etc

we should set a 🔒 flag on the content, and no edit or comments will be made/append

a possible prototype may look like this:

field(:lock, :string)
belongs_to(:lock_operator, User)

and if front-end want the lock history, should check the inner-logger, see: #104

pin contents may effect performance

currently the pin contents execs 2 query on the same contents table:

  def paged_contents(queryable, filter) do
    queryable
    |> flag_query(filter)
    |> ORM.find_all(filter)
    |> add_pin_contents_ifneed(queryable, filter)
  end

  defp flag_query(queryable, filter, flag \\ %{}) do
    flag = %{pin: false, trash: false} |> Map.merge(flag)

    # NOTE: this case judge is used for test case
    case filter |> Map.has_key?(:community) do
      true ->
        queryable
        |> join(:inner, [q], f in assoc(q, :community_flags))
        |> where([q, f], f.pin == ^flag.pin and f.trash == ^flag.trash)
        |> join(:inner, [q, f], c in assoc(f, :community))
        |> where([q, f, c], c.raw == ^filter.community)

      false ->
        queryable
    end
  end

  defp add_pin_contents_ifneed(contents, queryable, filter) do
    with {:ok, normal_contents} <- contents,
         true <- Map.has_key?(filter, :community),
         true <- 1 == Map.get(normal_contents, :page_number) do
      {:ok, pined_content} =
        queryable
        |> flag_query(filter, %{pin: true})
        |> ORM.find_all(filter)

      # TODO: add hot post pin/trash state ?
      # don't by flag_changeset, dataloader make things complex
      concat_contents(pined_content, normal_contents)
    else
      _error ->
        contents
    end
  end

when the contents table growing big, the "add_pin_contents_ifneed" function will query all the contents only for few pined contents, this's may have performance issue.

i think the better practice is: we split pined contents into a new separate table, then combine the small pined query results to all the results.

"Top N per Group" example in Dataloader

Currently the xxx-users loader is not using Dataloader , because the limit and offset in the query will affect the whole result set and not each association, this can be solved by a "Top N per Group" case, but the syntax is ugly ...

reference links:

https://elixirforum.com/t/preloading-top-comments-for-posts-in-ecto/1052/8
elixir-ecto/ecto#2281
https://spin.atomicobject.com/2016/03/12/select-top-n-per-group-postgresql/
https://stackoverflow.com/questions/40529699/how-to-select-id-with-max-date-group-by-category-in-ecto-query-with-phoenix
http://www.achraf-sallemi.com/select-top-n-per-group-in-postgresql/

tipping via QR code

thoughts

  1. only advance account can set tip QR info
  2. QR code(if set) should appear in user-page / article-bottom

Video threads

thought

first of all: video should be links, i am poor ..

  1. currently most of the videos should be youtubes
  2. video should have post, duration, desc, source, source_link, published_at,video_author but NOT playtimes
  3. should have category, playlist concept
  4. only community editors can CURD videos

delete related OSS resource when delete article content

  1. 在 article 类资源上增加 attachments 字段,包含该 article 里面的 图片等连接信息
  2. 删除资源的同时应该同时删除放在OSS 上的 attachments 资源
  3. 目前 attachments 由前段解析提供,后期应该在后端再做一次校验
  4. 同3, Elixir 里的正则表达式比较蛋疼。。

add user reputation

details

(like / star / comment) by sb => reputation +1
(favorite) by sb => reputation +2

async job support

e.g :

  1. last vist time statistic ...
  2. log ...
  3. send emails ..

seems rihanna is the best tool, not need redis
and most powerful pkg: exq

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.